@sb1/ffe-file-upload-react 10.0.52 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/FileItem.js +2 -20
- package/es/FileUpload.js +106 -197
- package/es/FileUpload.spec.js +62 -0
- package/es/{file-content.js → getFileContent.js} +1 -1
- package/es/index.js +2 -3
- package/lib/FileItem.js +3 -21
- package/lib/FileUpload.js +109 -197
- package/lib/FileUpload.spec.js +65 -0
- package/lib/{file-content.js → getFileContent.js} +1 -1
- package/lib/index.js +15 -6
- package/package.json +9 -10
- package/es/index.d.js +0 -1
- package/lib/index.d.js +0 -6
- package/types/index.d.ts +0 -32
package/es/FileItem.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { func, shape, object, string as stringType } from 'prop-types';
|
|
3
2
|
import { Icon } from '@sb1/ffe-icons-react';
|
|
4
|
-
|
|
3
|
+
export function FileItem(_ref) {
|
|
5
4
|
var file = _ref.file,
|
|
6
5
|
onFileDeleted = _ref.onFileDeleted,
|
|
7
6
|
cancelText = _ref.cancelText,
|
|
@@ -74,21 +73,4 @@ var FileItem = function FileItem(_ref) {
|
|
|
74
73
|
}, file.name), /*#__PURE__*/React.createElement("div", {
|
|
75
74
|
className: "ffe-file-upload__file-item-error-message"
|
|
76
75
|
}, file.error))));
|
|
77
|
-
}
|
|
78
|
-
FileItem.propTypes = {
|
|
79
|
-
/** Shape of the file type, name is required, error and document.content is optional */
|
|
80
|
-
file: shape({
|
|
81
|
-
name: stringType.isRequired,
|
|
82
|
-
document: object,
|
|
83
|
-
error: stringType
|
|
84
|
-
}).isRequired,
|
|
85
|
-
/**
|
|
86
|
-
* Called when the user clicks the delete button for a given file. Is called with the name of the file in question.
|
|
87
|
-
*/
|
|
88
|
-
onFileDeleted: func.isRequired,
|
|
89
|
-
/** Label for the cancel button */
|
|
90
|
-
cancelText: stringType,
|
|
91
|
-
/** Label for the delete button */
|
|
92
|
-
deleteText: stringType
|
|
93
|
-
};
|
|
94
|
-
export default FileItem;
|
|
76
|
+
}
|
package/es/FileUpload.js
CHANGED
|
@@ -1,203 +1,112 @@
|
|
|
1
|
-
function
|
|
2
|
-
function
|
|
3
|
-
function
|
|
4
|
-
function
|
|
5
|
-
function
|
|
6
|
-
function
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
10
|
-
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
11
|
-
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
12
|
-
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
13
|
-
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
14
|
-
import React from 'react';
|
|
15
|
-
import { object, bool, func, string as stringType } from 'prop-types';
|
|
16
|
-
import FileItem from './FileItem';
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import React, { useRef, useState } from 'react';
|
|
8
|
+
import { FileItem } from './FileItem';
|
|
17
9
|
import classNames from 'classnames';
|
|
18
10
|
import { SecondaryButton } from '@sb1/ffe-buttons-react';
|
|
19
11
|
import { Icon } from '@sb1/ffe-icons-react';
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
12
|
+
export function FileUpload(_ref) {
|
|
13
|
+
var id = _ref.id,
|
|
14
|
+
label = _ref.label,
|
|
15
|
+
files = _ref.files,
|
|
16
|
+
cancelText = _ref.cancelText,
|
|
17
|
+
deleteText = _ref.deleteText,
|
|
18
|
+
multiple = _ref.multiple,
|
|
19
|
+
title = _ref.title,
|
|
20
|
+
infoText = _ref.infoText,
|
|
21
|
+
infoSubText = _ref.infoSubText,
|
|
22
|
+
uploadTitle = _ref.uploadTitle,
|
|
23
|
+
uploadMicroText = _ref.uploadMicroText,
|
|
24
|
+
uploadSubText = _ref.uploadSubText,
|
|
25
|
+
accept = _ref.accept,
|
|
26
|
+
onFilesDropped = _ref.onFilesDropped,
|
|
27
|
+
onFileDeleted = _ref.onFileDeleted,
|
|
28
|
+
onFilesSelected = _ref.onFilesSelected;
|
|
29
|
+
var _useState = useState(false),
|
|
30
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
31
|
+
isHover = _useState2[0],
|
|
32
|
+
setIsHover = _useState2[1];
|
|
33
|
+
var fileInputElement = useRef(null);
|
|
34
|
+
var downloadIcon = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iMjAiPjxwYXRoIGQ9Ik00NzkuOC0zNTcuNTM5cS02LjQzMSAwLTExLjk2MS0yLjMwOC01LjUzMS0yLjMwNy0xMC4xNDYtNi45MjNMMzM1LjMwOS00ODkuMTUzcS03LjkyMy03LjgzMi03LjgwNy0xOC4zMzguMTE1LTEwLjUwNyA4LjMyOS0xOC44MTUgOC43ODYtOC4zMDcgMTguODYyLTguMTE1IDEwLjA3Ny4xOTIgMTguMzg1IDguNWw4MC45MjMgODEuOTIzdi0zMjYuMDAxcTAtMTEuMDY5IDcuNDA0LTE4LjUzNCA3LjQwNS03LjQ2NiAxOC4zODQtNy40NjYgMTAuOTggMCAxOC41OTUgNy40NjYgNy42MTUgNy40NjUgNy42MTUgMTguNTM0djMyNi4wMDFsODEuOTIzLTgxLjkyM3E3LjU5LTcuOTIzIDE4LjAyNi03LjgwOCAxMC40MzUuMTE2IDE5LjIyMSA4LjQyMyA4LjIxNCA4LjMwOCA4LjAyMSAxOC41NzctLjE5MiAxMC4yNjktOC40OTkgMTguNTc2TDUwMi4zMDctMzY2Ljc3cS01LjAxNSA0LjYxNi0xMC41NDYgNi45MjMtNS41MyAyLjMwOC0xMS45NjEgMi4zMDhaTTI3Ni4wMjUtMjEyLjAwMXEtMjcuMDI0IDAtNDUuNTI0LTE4LjY1dC0xOC41LTQ1LjY1OHYtMzQuNDYxcTAtMTEuMDY5IDcuNDA1LTE4LjUzNCA3LjQwNS03LjQ2NSAxOC4zODQtNy40NjUgMTAuOTggMCAxOC41OTUgNy40NjVRMjY0LTMyMS44MzkgMjY0LTMxMC43N3YzNC40NjFxMCA0LjYxNiAzLjg0NiA4LjQ2MyAzLjg0NyAzLjg0NiA4LjQ2MyAzLjg0Nmg0MDcuMzgycTQuNjE2IDAgOC40NjMtMy44NDYgMy44NDYtMy44NDcgMy44NDYtOC40NjN2LTM0LjQ2MXEwLTExLjA2OSA3LjQwNS0xOC41MzQgNy40MDQtNy40NjUgMTguMzg0LTcuNDY1IDEwLjk3OSAwIDE4LjU5NCA3LjQ2NSA3LjYxNiA3LjQ2NSA3LjYxNiAxOC41MzR2MzQuNDYxcTAgMjcuMDA4LTE4LjY2MiA0NS42NTgtMTguNjYyIDE4LjY1LTQ1LjY4NiAxOC42NUgyNzYuMDI1WiIvPjwvc3ZnPg==';
|
|
35
|
+
var handleFilesDropped = function handleFilesDropped(event) {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
setIsHover(false);
|
|
38
|
+
onFilesDropped(event.dataTransfer.files);
|
|
39
|
+
};
|
|
40
|
+
var handleFileDeleted = function handleFileDeleted(event) {
|
|
41
|
+
onFileDeleted(files[event.currentTarget.id]);
|
|
42
|
+
};
|
|
43
|
+
var triggerUploadFileNativeHandler = function triggerUploadFileNativeHandler() {
|
|
44
|
+
// clear file input to trigger onChange when uploading same filename
|
|
45
|
+
if (fileInputElement.current) {
|
|
46
|
+
fileInputElement.current.value = '';
|
|
47
|
+
fileInputElement.current.click();
|
|
40
48
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
};
|
|
50
|
+
var handleFileSelected = function handleFileSelected(event) {
|
|
51
|
+
onFilesSelected(event.target.files);
|
|
52
|
+
};
|
|
53
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
54
|
+
className: "ffe-file-upload"
|
|
55
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
56
|
+
className: "ffe-file-upload__title"
|
|
57
|
+
}, title), Object.keys(files).length > 0 ? /*#__PURE__*/React.createElement("div", {
|
|
58
|
+
className: "ffe-file-upload__file-items-section"
|
|
59
|
+
}, Object.keys(files).map(function (file) {
|
|
60
|
+
return /*#__PURE__*/React.createElement(FileItem, {
|
|
61
|
+
key: file,
|
|
62
|
+
file: files[file],
|
|
63
|
+
cancelText: cancelText,
|
|
64
|
+
deleteText: deleteText,
|
|
65
|
+
onFileDeleted: handleFileDeleted
|
|
66
|
+
});
|
|
67
|
+
})) : /*#__PURE__*/React.createElement("div", {
|
|
68
|
+
className: "ffe-file-upload__info-section"
|
|
69
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
70
|
+
className: "ffe-file-upload__info-section-text"
|
|
71
|
+
}, infoText), /*#__PURE__*/React.createElement("div", {
|
|
72
|
+
className: "ffe-file-upload__info-section-subtext"
|
|
73
|
+
}, infoSubText)), /*#__PURE__*/React.createElement("div", {
|
|
74
|
+
className: "ffe-file-upload__upload-section",
|
|
75
|
+
role: "presentation",
|
|
76
|
+
onDrop: handleFilesDropped,
|
|
77
|
+
onDragOver: function onDragOver(event) {
|
|
58
78
|
event.preventDefault();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
}, {
|
|
65
|
-
key: "onFileDeleted",
|
|
66
|
-
value: function onFileDeleted(event) {
|
|
67
|
-
this.props.onFileDeleted(this.props.files[event.currentTarget.id]);
|
|
68
|
-
}
|
|
69
|
-
}, {
|
|
70
|
-
key: "render",
|
|
71
|
-
value: function render() {
|
|
72
|
-
var _this2 = this;
|
|
73
|
-
var _this$props = this.props,
|
|
74
|
-
id = _this$props.id,
|
|
75
|
-
label = _this$props.label,
|
|
76
|
-
files = _this$props.files,
|
|
77
|
-
cancelText = _this$props.cancelText,
|
|
78
|
-
deleteText = _this$props.deleteText,
|
|
79
|
-
multiple = _this$props.multiple,
|
|
80
|
-
title = _this$props.title,
|
|
81
|
-
infoText = _this$props.infoText,
|
|
82
|
-
infoSubText = _this$props.infoSubText,
|
|
83
|
-
uploadTitle = _this$props.uploadTitle,
|
|
84
|
-
uploadMicroText = _this$props.uploadMicroText,
|
|
85
|
-
uploadSubText = _this$props.uploadSubText,
|
|
86
|
-
accept = _this$props.accept;
|
|
87
|
-
var downloadIcon = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iMjAiPjxwYXRoIGQ9Ik00NzkuOC0zNTcuNTM5cS02LjQzMSAwLTExLjk2MS0yLjMwOC01LjUzMS0yLjMwNy0xMC4xNDYtNi45MjNMMzM1LjMwOS00ODkuMTUzcS03LjkyMy03LjgzMi03LjgwNy0xOC4zMzguMTE1LTEwLjUwNyA4LjMyOS0xOC44MTUgOC43ODYtOC4zMDcgMTguODYyLTguMTE1IDEwLjA3Ny4xOTIgMTguMzg1IDguNWw4MC45MjMgODEuOTIzdi0zMjYuMDAxcTAtMTEuMDY5IDcuNDA0LTE4LjUzNCA3LjQwNS03LjQ2NiAxOC4zODQtNy40NjYgMTAuOTggMCAxOC41OTUgNy40NjYgNy42MTUgNy40NjUgNy42MTUgMTguNTM0djMyNi4wMDFsODEuOTIzLTgxLjkyM3E3LjU5LTcuOTIzIDE4LjAyNi03LjgwOCAxMC40MzUuMTE2IDE5LjIyMSA4LjQyMyA4LjIxNCA4LjMwOCA4LjAyMSAxOC41NzctLjE5MiAxMC4yNjktOC40OTkgMTguNTc2TDUwMi4zMDctMzY2Ljc3cS01LjAxNSA0LjYxNi0xMC41NDYgNi45MjMtNS41MyAyLjMwOC0xMS45NjEgMi4zMDhaTTI3Ni4wMjUtMjEyLjAwMXEtMjcuMDI0IDAtNDUuNTI0LTE4LjY1dC0xOC41LTQ1LjY1OHYtMzQuNDYxcTAtMTEuMDY5IDcuNDA1LTE4LjUzNCA3LjQwNS03LjQ2NSAxOC4zODQtNy40NjUgMTAuOTggMCAxOC41OTUgNy40NjVRMjY0LTMyMS44MzkgMjY0LTMxMC43N3YzNC40NjFxMCA0LjYxNiAzLjg0NiA4LjQ2MyAzLjg0NyAzLjg0NiA4LjQ2MyAzLjg0Nmg0MDcuMzgycTQuNjE2IDAgOC40NjMtMy44NDYgMy44NDYtMy44NDcgMy44NDYtOC40NjN2LTM0LjQ2MXEwLTExLjA2OSA3LjQwNS0xOC41MzQgNy40MDQtNy40NjUgMTguMzg0LTcuNDY1IDEwLjk3OSAwIDE4LjU5NCA3LjQ2NSA3LjYxNiA3LjQ2NSA3LjYxNiAxOC41MzR2MzQuNDYxcTAgMjcuMDA4LTE4LjY2MiA0NS42NTgtMTguNjYyIDE4LjY1LTQ1LjY4NiAxOC42NUgyNzYuMDI1WiIvPjwvc3ZnPg==';
|
|
88
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
89
|
-
className: "ffe-file-upload"
|
|
90
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
91
|
-
className: "ffe-file-upload__title"
|
|
92
|
-
}, title), Object.keys(files).length > 0 ? /*#__PURE__*/React.createElement("div", {
|
|
93
|
-
className: "ffe-file-upload__file-items-section"
|
|
94
|
-
}, Object.keys(files).map(function (file) {
|
|
95
|
-
return /*#__PURE__*/React.createElement(FileItem, {
|
|
96
|
-
key: file,
|
|
97
|
-
file: files[file],
|
|
98
|
-
cancelText: cancelText,
|
|
99
|
-
deleteText: deleteText,
|
|
100
|
-
onFileDeleted: _this2.onFileDeleted
|
|
101
|
-
});
|
|
102
|
-
})) : /*#__PURE__*/React.createElement("div", {
|
|
103
|
-
className: "ffe-file-upload__info-section"
|
|
104
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
105
|
-
className: "ffe-file-upload__info-section-text"
|
|
106
|
-
}, infoText), /*#__PURE__*/React.createElement("div", {
|
|
107
|
-
className: "ffe-file-upload__info-section-subtext"
|
|
108
|
-
}, infoSubText)), /*#__PURE__*/React.createElement("div", {
|
|
109
|
-
className: "ffe-file-upload__upload-section",
|
|
110
|
-
role: "presentation",
|
|
111
|
-
onDrop: this.onFilesDropped,
|
|
112
|
-
onDragOver: function onDragOver(event) {
|
|
113
|
-
event.preventDefault();
|
|
114
|
-
_this2.setState({
|
|
115
|
-
hover: true
|
|
116
|
-
});
|
|
117
|
-
},
|
|
118
|
-
onDragLeave: function onDragLeave() {
|
|
119
|
-
return _this2.setState({
|
|
120
|
-
hover: false
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
124
|
-
className: classNames('ffe-file-upload__upload-section-border', {
|
|
125
|
-
'ffe-file-upload__upload-section-border--hover': this.state.hover
|
|
126
|
-
})
|
|
127
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
128
|
-
className: "ffe-file-upload__upload-section-title"
|
|
129
|
-
}, uploadTitle), /*#__PURE__*/React.createElement("div", {
|
|
130
|
-
className: "ffe-file-upload__upload-section-microtext"
|
|
131
|
-
}, uploadMicroText), /*#__PURE__*/React.createElement(SecondaryButton, {
|
|
132
|
-
leftIcon: /*#__PURE__*/React.createElement(Icon, {
|
|
133
|
-
fileUrl: downloadIcon,
|
|
134
|
-
size: "sm"
|
|
135
|
-
}),
|
|
136
|
-
onClick: this.triggerUploadFileNativeHandler,
|
|
137
|
-
id: "".concat(id, "-button")
|
|
138
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
139
|
-
id: "".concat(id, "-label")
|
|
140
|
-
}, label)), /*#__PURE__*/React.createElement("div", {
|
|
141
|
-
className: "ffe-file-upload__upload-section-subtext"
|
|
142
|
-
}, uploadSubText))), /*#__PURE__*/React.createElement("input", {
|
|
143
|
-
id: id,
|
|
144
|
-
type: "file",
|
|
145
|
-
multiple: multiple,
|
|
146
|
-
ref: this.setFileInputElement,
|
|
147
|
-
onChange: this.onFilesSelected,
|
|
148
|
-
"aria-labelledby": "".concat(id, "-label"),
|
|
149
|
-
accept: accept || '*'
|
|
150
|
-
}));
|
|
79
|
+
setIsHover(true);
|
|
80
|
+
},
|
|
81
|
+
onDragLeave: function onDragLeave() {
|
|
82
|
+
return setIsHover(false);
|
|
151
83
|
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
/** Title module */
|
|
182
|
-
title: stringType.isRequired,
|
|
183
|
-
/** Text on the info-section */
|
|
184
|
-
infoText: stringType.isRequired,
|
|
185
|
-
/** Subtext on the info-section */
|
|
186
|
-
infoSubText: stringType,
|
|
187
|
-
/** Label for the cancel button */
|
|
188
|
-
cancelText: stringType,
|
|
189
|
-
/** Label for the delete button */
|
|
190
|
-
deleteText: stringType,
|
|
191
|
-
/** Title on the upload-section */
|
|
192
|
-
uploadTitle: stringType.isRequired,
|
|
193
|
-
/** MicroText on the upload-section */
|
|
194
|
-
uploadMicroText: stringType.isRequired,
|
|
195
|
-
/** SubText on the upload-section */
|
|
196
|
-
uploadSubText: stringType.isRequired,
|
|
197
|
-
/** Unique file type specifier that describes a type of file that may be selected by the user, e.g. ".pdf"
|
|
198
|
-
* See MDN for documentation on
|
|
199
|
-
* [Unique file type specifiers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers)
|
|
200
|
-
*/
|
|
201
|
-
accept: stringType
|
|
202
|
-
};
|
|
203
|
-
export default FileUpload;
|
|
84
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
85
|
+
className: classNames('ffe-file-upload__upload-section-border', {
|
|
86
|
+
'ffe-file-upload__upload-section-border--hover': isHover
|
|
87
|
+
})
|
|
88
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
89
|
+
className: "ffe-file-upload__upload-section-title"
|
|
90
|
+
}, uploadTitle), /*#__PURE__*/React.createElement("div", {
|
|
91
|
+
className: "ffe-file-upload__upload-section-microtext"
|
|
92
|
+
}, uploadMicroText), /*#__PURE__*/React.createElement(SecondaryButton, {
|
|
93
|
+
leftIcon: /*#__PURE__*/React.createElement(Icon, {
|
|
94
|
+
fileUrl: downloadIcon,
|
|
95
|
+
size: "sm"
|
|
96
|
+
}),
|
|
97
|
+
onClick: triggerUploadFileNativeHandler,
|
|
98
|
+
id: "".concat(id, "-button")
|
|
99
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
100
|
+
id: "".concat(id, "-label")
|
|
101
|
+
}, label)), /*#__PURE__*/React.createElement("div", {
|
|
102
|
+
className: "ffe-file-upload__upload-section-subtext"
|
|
103
|
+
}, uploadSubText))), /*#__PURE__*/React.createElement("input", {
|
|
104
|
+
id: id,
|
|
105
|
+
type: "file",
|
|
106
|
+
multiple: multiple,
|
|
107
|
+
ref: fileInputElement,
|
|
108
|
+
onChange: handleFileSelected,
|
|
109
|
+
"aria-labelledby": "".concat(id, "-label"),
|
|
110
|
+
accept: accept || '*'
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { spy } from 'sinon';
|
|
4
|
+
import { FileUpload } from './FileUpload';
|
|
5
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
6
|
+
var renderFileUpload = function renderFileUpload(props) {
|
|
7
|
+
return render( /*#__PURE__*/React.createElement(FileUpload, _extends({
|
|
8
|
+
id: "file-upload",
|
|
9
|
+
label: "label",
|
|
10
|
+
title: "title",
|
|
11
|
+
infoText: "infoText",
|
|
12
|
+
uploadTitle: "uploadTitle",
|
|
13
|
+
uploadMicroText: "uploadMicroText",
|
|
14
|
+
uploadSubText: "uploadSubText",
|
|
15
|
+
files: {},
|
|
16
|
+
onFilesSelected: function onFilesSelected() {},
|
|
17
|
+
onFileDeleted: function onFileDeleted() {},
|
|
18
|
+
onFilesDropped: function onFilesDropped() {}
|
|
19
|
+
}, props)));
|
|
20
|
+
};
|
|
21
|
+
describe('<FileUpload/>', function () {
|
|
22
|
+
it('should have a button and input', function () {
|
|
23
|
+
var _renderFileUpload = renderFileUpload(),
|
|
24
|
+
container = _renderFileUpload.container;
|
|
25
|
+
expect(container.querySelector('#file-upload-button')).toBeTruthy();
|
|
26
|
+
expect(container.querySelector('#file-upload')).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
it('should render input label', function () {
|
|
29
|
+
renderFileUpload();
|
|
30
|
+
expect(screen.getByRole('button', {
|
|
31
|
+
name: 'label'
|
|
32
|
+
})).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
it('should extract and return files when user finishes selecting files', function () {
|
|
35
|
+
var onFilesSelected = spy();
|
|
36
|
+
var _renderFileUpload2 = renderFileUpload({
|
|
37
|
+
onFilesSelected: onFilesSelected
|
|
38
|
+
}),
|
|
39
|
+
container = _renderFileUpload2.container;
|
|
40
|
+
var input = container.querySelector('input#file-upload');
|
|
41
|
+
fireEvent.change(input);
|
|
42
|
+
expect(onFilesSelected.calledOnce).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
it('should remove file from files when delete button is clicked', function () {
|
|
45
|
+
var onFileDeleted = spy();
|
|
46
|
+
// Do click on span inside button with event listener instead of actual button to catch nested clicks.
|
|
47
|
+
var _renderFileUpload3 = renderFileUpload({
|
|
48
|
+
onFileDeleted: onFileDeleted,
|
|
49
|
+
files: {
|
|
50
|
+
fileToDelete: {
|
|
51
|
+
name: 'fileToDelete'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}),
|
|
55
|
+
container = _renderFileUpload3.container;
|
|
56
|
+
var deleteButton = container.querySelector('.ffe-file-upload__file-item-delete-button-text');
|
|
57
|
+
fireEvent.click(deleteButton);
|
|
58
|
+
expect(onFileDeleted.calledWith({
|
|
59
|
+
name: 'fileToDelete'
|
|
60
|
+
})).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -2,7 +2,7 @@ export var getFileContent = function getFileContent(file) {
|
|
|
2
2
|
return new Promise(function (resolve, reject) {
|
|
3
3
|
var reader = new window.FileReader();
|
|
4
4
|
reader.onload = function (event) {
|
|
5
|
-
return resolve(event.target.result);
|
|
5
|
+
return resolve(event.target ? event.target.result : null);
|
|
6
6
|
};
|
|
7
7
|
reader.onerror = function (error) {
|
|
8
8
|
return reject(error);
|
package/es/index.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export { getFileContent } from './
|
|
3
|
-
export default FileUpload;
|
|
1
|
+
export { FileUpload, FileUploadProps } from './FileUpload';
|
|
2
|
+
export { getFileContent } from './getFileContent';
|
package/lib/FileItem.js
CHANGED
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.FileItem = FileItem;
|
|
7
7
|
var _react = _interopRequireDefault(require("react"));
|
|
8
|
-
var _propTypes = require("prop-types");
|
|
9
8
|
var _ffeIconsReact = require("@sb1/ffe-icons-react");
|
|
10
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
-
|
|
10
|
+
function FileItem(_ref) {
|
|
12
11
|
var file = _ref.file,
|
|
13
12
|
onFileDeleted = _ref.onFileDeleted,
|
|
14
13
|
cancelText = _ref.cancelText,
|
|
@@ -81,21 +80,4 @@ var FileItem = function FileItem(_ref) {
|
|
|
81
80
|
}, file.name), /*#__PURE__*/_react.default.createElement("div", {
|
|
82
81
|
className: "ffe-file-upload__file-item-error-message"
|
|
83
82
|
}, file.error))));
|
|
84
|
-
}
|
|
85
|
-
FileItem.propTypes = {
|
|
86
|
-
/** Shape of the file type, name is required, error and document.content is optional */
|
|
87
|
-
file: (0, _propTypes.shape)({
|
|
88
|
-
name: _propTypes.string.isRequired,
|
|
89
|
-
document: _propTypes.object,
|
|
90
|
-
error: _propTypes.string
|
|
91
|
-
}).isRequired,
|
|
92
|
-
/**
|
|
93
|
-
* Called when the user clicks the delete button for a given file. Is called with the name of the file in question.
|
|
94
|
-
*/
|
|
95
|
-
onFileDeleted: _propTypes.func.isRequired,
|
|
96
|
-
/** Label for the cancel button */
|
|
97
|
-
cancelText: _propTypes.string,
|
|
98
|
-
/** Label for the delete button */
|
|
99
|
-
deleteText: _propTypes.string
|
|
100
|
-
};
|
|
101
|
-
var _default = exports.default = FileItem;
|
|
83
|
+
}
|
package/lib/FileUpload.js
CHANGED
|
@@ -4,207 +4,119 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.
|
|
8
|
-
var _react =
|
|
9
|
-
var
|
|
10
|
-
var _FileItem = _interopRequireDefault(require("./FileItem"));
|
|
7
|
+
exports.FileUpload = FileUpload;
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _FileItem = require("./FileItem");
|
|
11
10
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
12
11
|
var _ffeButtonsReact = require("@sb1/ffe-buttons-react");
|
|
13
12
|
var _ffeIconsReact = require("@sb1/ffe-icons-react");
|
|
14
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
function
|
|
16
|
-
function
|
|
17
|
-
function
|
|
18
|
-
function
|
|
19
|
-
function
|
|
20
|
-
function
|
|
21
|
-
function
|
|
22
|
-
function
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
14
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
15
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
16
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
17
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
18
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
19
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
20
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
21
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
22
|
+
function FileUpload(_ref) {
|
|
23
|
+
var id = _ref.id,
|
|
24
|
+
label = _ref.label,
|
|
25
|
+
files = _ref.files,
|
|
26
|
+
cancelText = _ref.cancelText,
|
|
27
|
+
deleteText = _ref.deleteText,
|
|
28
|
+
multiple = _ref.multiple,
|
|
29
|
+
title = _ref.title,
|
|
30
|
+
infoText = _ref.infoText,
|
|
31
|
+
infoSubText = _ref.infoSubText,
|
|
32
|
+
uploadTitle = _ref.uploadTitle,
|
|
33
|
+
uploadMicroText = _ref.uploadMicroText,
|
|
34
|
+
uploadSubText = _ref.uploadSubText,
|
|
35
|
+
accept = _ref.accept,
|
|
36
|
+
onFilesDropped = _ref.onFilesDropped,
|
|
37
|
+
onFileDeleted = _ref.onFileDeleted,
|
|
38
|
+
onFilesSelected = _ref.onFilesSelected;
|
|
39
|
+
var _useState = (0, _react.useState)(false),
|
|
40
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
41
|
+
isHover = _useState2[0],
|
|
42
|
+
setIsHover = _useState2[1];
|
|
43
|
+
var fileInputElement = (0, _react.useRef)(null);
|
|
44
|
+
var downloadIcon = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iMjAiPjxwYXRoIGQ9Ik00NzkuOC0zNTcuNTM5cS02LjQzMSAwLTExLjk2MS0yLjMwOC01LjUzMS0yLjMwNy0xMC4xNDYtNi45MjNMMzM1LjMwOS00ODkuMTUzcS03LjkyMy03LjgzMi03LjgwNy0xOC4zMzguMTE1LTEwLjUwNyA4LjMyOS0xOC44MTUgOC43ODYtOC4zMDcgMTguODYyLTguMTE1IDEwLjA3Ny4xOTIgMTguMzg1IDguNWw4MC45MjMgODEuOTIzdi0zMjYuMDAxcTAtMTEuMDY5IDcuNDA0LTE4LjUzNCA3LjQwNS03LjQ2NiAxOC4zODQtNy40NjYgMTAuOTggMCAxOC41OTUgNy40NjYgNy42MTUgNy40NjUgNy42MTUgMTguNTM0djMyNi4wMDFsODEuOTIzLTgxLjkyM3E3LjU5LTcuOTIzIDE4LjAyNi03LjgwOCAxMC40MzUuMTE2IDE5LjIyMSA4LjQyMyA4LjIxNCA4LjMwOCA4LjAyMSAxOC41NzctLjE5MiAxMC4yNjktOC40OTkgMTguNTc2TDUwMi4zMDctMzY2Ljc3cS01LjAxNSA0LjYxNi0xMC41NDYgNi45MjMtNS41MyAyLjMwOC0xMS45NjEgMi4zMDhaTTI3Ni4wMjUtMjEyLjAwMXEtMjcuMDI0IDAtNDUuNTI0LTE4LjY1dC0xOC41LTQ1LjY1OHYtMzQuNDYxcTAtMTEuMDY5IDcuNDA1LTE4LjUzNCA3LjQwNS03LjQ2NSAxOC4zODQtNy40NjUgMTAuOTggMCAxOC41OTUgNy40NjVRMjY0LTMyMS44MzkgMjY0LTMxMC43N3YzNC40NjFxMCA0LjYxNiAzLjg0NiA4LjQ2MyAzLjg0NyAzLjg0NiA4LjQ2MyAzLjg0Nmg0MDcuMzgycTQuNjE2IDAgOC40NjMtMy44NDYgMy44NDYtMy44NDcgMy44NDYtOC40NjN2LTM0LjQ2MXEwLTExLjA2OSA3LjQwNS0xOC41MzQgNy40MDQtNy40NjUgMTguMzg0LTcuNDY1IDEwLjk3OSAwIDE4LjU5NCA3LjQ2NSA3LjYxNiA3LjQ2NSA3LjYxNiAxOC41MzR2MzQuNDYxcTAgMjcuMDA4LTE4LjY2MiA0NS42NTgtMTguNjYyIDE4LjY1LTQ1LjY4NiAxOC42NUgyNzYuMDI1WiIvPjwvc3ZnPg==';
|
|
45
|
+
var handleFilesDropped = function handleFilesDropped(event) {
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
setIsHover(false);
|
|
48
|
+
onFilesDropped(event.dataTransfer.files);
|
|
49
|
+
};
|
|
50
|
+
var handleFileDeleted = function handleFileDeleted(event) {
|
|
51
|
+
onFileDeleted(files[event.currentTarget.id]);
|
|
52
|
+
};
|
|
53
|
+
var triggerUploadFileNativeHandler = function triggerUploadFileNativeHandler() {
|
|
54
|
+
// clear file input to trigger onChange when uploading same filename
|
|
55
|
+
if (fileInputElement.current) {
|
|
56
|
+
fileInputElement.current.value = '';
|
|
57
|
+
fileInputElement.current.click();
|
|
47
58
|
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
};
|
|
60
|
+
var handleFileSelected = function handleFileSelected(event) {
|
|
61
|
+
onFilesSelected(event.target.files);
|
|
62
|
+
};
|
|
63
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
64
|
+
className: "ffe-file-upload"
|
|
65
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
66
|
+
className: "ffe-file-upload__title"
|
|
67
|
+
}, title), Object.keys(files).length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
|
|
68
|
+
className: "ffe-file-upload__file-items-section"
|
|
69
|
+
}, Object.keys(files).map(function (file) {
|
|
70
|
+
return /*#__PURE__*/_react.default.createElement(_FileItem.FileItem, {
|
|
71
|
+
key: file,
|
|
72
|
+
file: files[file],
|
|
73
|
+
cancelText: cancelText,
|
|
74
|
+
deleteText: deleteText,
|
|
75
|
+
onFileDeleted: handleFileDeleted
|
|
76
|
+
});
|
|
77
|
+
})) : /*#__PURE__*/_react.default.createElement("div", {
|
|
78
|
+
className: "ffe-file-upload__info-section"
|
|
79
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
80
|
+
className: "ffe-file-upload__info-section-text"
|
|
81
|
+
}, infoText), /*#__PURE__*/_react.default.createElement("div", {
|
|
82
|
+
className: "ffe-file-upload__info-section-subtext"
|
|
83
|
+
}, infoSubText)), /*#__PURE__*/_react.default.createElement("div", {
|
|
84
|
+
className: "ffe-file-upload__upload-section",
|
|
85
|
+
role: "presentation",
|
|
86
|
+
onDrop: handleFilesDropped,
|
|
87
|
+
onDragOver: function onDragOver(event) {
|
|
65
88
|
event.preventDefault();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
}, {
|
|
72
|
-
key: "onFileDeleted",
|
|
73
|
-
value: function onFileDeleted(event) {
|
|
74
|
-
this.props.onFileDeleted(this.props.files[event.currentTarget.id]);
|
|
75
|
-
}
|
|
76
|
-
}, {
|
|
77
|
-
key: "render",
|
|
78
|
-
value: function render() {
|
|
79
|
-
var _this2 = this;
|
|
80
|
-
var _this$props = this.props,
|
|
81
|
-
id = _this$props.id,
|
|
82
|
-
label = _this$props.label,
|
|
83
|
-
files = _this$props.files,
|
|
84
|
-
cancelText = _this$props.cancelText,
|
|
85
|
-
deleteText = _this$props.deleteText,
|
|
86
|
-
multiple = _this$props.multiple,
|
|
87
|
-
title = _this$props.title,
|
|
88
|
-
infoText = _this$props.infoText,
|
|
89
|
-
infoSubText = _this$props.infoSubText,
|
|
90
|
-
uploadTitle = _this$props.uploadTitle,
|
|
91
|
-
uploadMicroText = _this$props.uploadMicroText,
|
|
92
|
-
uploadSubText = _this$props.uploadSubText,
|
|
93
|
-
accept = _this$props.accept;
|
|
94
|
-
var downloadIcon = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iMjAiPjxwYXRoIGQ9Ik00NzkuOC0zNTcuNTM5cS02LjQzMSAwLTExLjk2MS0yLjMwOC01LjUzMS0yLjMwNy0xMC4xNDYtNi45MjNMMzM1LjMwOS00ODkuMTUzcS03LjkyMy03LjgzMi03LjgwNy0xOC4zMzguMTE1LTEwLjUwNyA4LjMyOS0xOC44MTUgOC43ODYtOC4zMDcgMTguODYyLTguMTE1IDEwLjA3Ny4xOTIgMTguMzg1IDguNWw4MC45MjMgODEuOTIzdi0zMjYuMDAxcTAtMTEuMDY5IDcuNDA0LTE4LjUzNCA3LjQwNS03LjQ2NiAxOC4zODQtNy40NjYgMTAuOTggMCAxOC41OTUgNy40NjYgNy42MTUgNy40NjUgNy42MTUgMTguNTM0djMyNi4wMDFsODEuOTIzLTgxLjkyM3E3LjU5LTcuOTIzIDE4LjAyNi03LjgwOCAxMC40MzUuMTE2IDE5LjIyMSA4LjQyMyA4LjIxNCA4LjMwOCA4LjAyMSAxOC41NzctLjE5MiAxMC4yNjktOC40OTkgMTguNTc2TDUwMi4zMDctMzY2Ljc3cS01LjAxNSA0LjYxNi0xMC41NDYgNi45MjMtNS41MyAyLjMwOC0xMS45NjEgMi4zMDhaTTI3Ni4wMjUtMjEyLjAwMXEtMjcuMDI0IDAtNDUuNTI0LTE4LjY1dC0xOC41LTQ1LjY1OHYtMzQuNDYxcTAtMTEuMDY5IDcuNDA1LTE4LjUzNCA3LjQwNS03LjQ2NSAxOC4zODQtNy40NjUgMTAuOTggMCAxOC41OTUgNy40NjVRMjY0LTMyMS44MzkgMjY0LTMxMC43N3YzNC40NjFxMCA0LjYxNiAzLjg0NiA4LjQ2MyAzLjg0NyAzLjg0NiA4LjQ2MyAzLjg0Nmg0MDcuMzgycTQuNjE2IDAgOC40NjMtMy44NDYgMy44NDYtMy44NDcgMy44NDYtOC40NjN2LTM0LjQ2MXEwLTExLjA2OSA3LjQwNS0xOC41MzQgNy40MDQtNy40NjUgMTguMzg0LTcuNDY1IDEwLjk3OSAwIDE4LjU5NCA3LjQ2NSA3LjYxNiA3LjQ2NSA3LjYxNiAxOC41MzR2MzQuNDYxcTAgMjcuMDA4LTE4LjY2MiA0NS42NTgtMTguNjYyIDE4LjY1LTQ1LjY4NiAxOC42NUgyNzYuMDI1WiIvPjwvc3ZnPg==';
|
|
95
|
-
return /*#__PURE__*/_react.default.createElement("div", {
|
|
96
|
-
className: "ffe-file-upload"
|
|
97
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
98
|
-
className: "ffe-file-upload__title"
|
|
99
|
-
}, title), Object.keys(files).length > 0 ? /*#__PURE__*/_react.default.createElement("div", {
|
|
100
|
-
className: "ffe-file-upload__file-items-section"
|
|
101
|
-
}, Object.keys(files).map(function (file) {
|
|
102
|
-
return /*#__PURE__*/_react.default.createElement(_FileItem.default, {
|
|
103
|
-
key: file,
|
|
104
|
-
file: files[file],
|
|
105
|
-
cancelText: cancelText,
|
|
106
|
-
deleteText: deleteText,
|
|
107
|
-
onFileDeleted: _this2.onFileDeleted
|
|
108
|
-
});
|
|
109
|
-
})) : /*#__PURE__*/_react.default.createElement("div", {
|
|
110
|
-
className: "ffe-file-upload__info-section"
|
|
111
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
112
|
-
className: "ffe-file-upload__info-section-text"
|
|
113
|
-
}, infoText), /*#__PURE__*/_react.default.createElement("div", {
|
|
114
|
-
className: "ffe-file-upload__info-section-subtext"
|
|
115
|
-
}, infoSubText)), /*#__PURE__*/_react.default.createElement("div", {
|
|
116
|
-
className: "ffe-file-upload__upload-section",
|
|
117
|
-
role: "presentation",
|
|
118
|
-
onDrop: this.onFilesDropped,
|
|
119
|
-
onDragOver: function onDragOver(event) {
|
|
120
|
-
event.preventDefault();
|
|
121
|
-
_this2.setState({
|
|
122
|
-
hover: true
|
|
123
|
-
});
|
|
124
|
-
},
|
|
125
|
-
onDragLeave: function onDragLeave() {
|
|
126
|
-
return _this2.setState({
|
|
127
|
-
hover: false
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
131
|
-
className: (0, _classnames.default)('ffe-file-upload__upload-section-border', {
|
|
132
|
-
'ffe-file-upload__upload-section-border--hover': this.state.hover
|
|
133
|
-
})
|
|
134
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
135
|
-
className: "ffe-file-upload__upload-section-title"
|
|
136
|
-
}, uploadTitle), /*#__PURE__*/_react.default.createElement("div", {
|
|
137
|
-
className: "ffe-file-upload__upload-section-microtext"
|
|
138
|
-
}, uploadMicroText), /*#__PURE__*/_react.default.createElement(_ffeButtonsReact.SecondaryButton, {
|
|
139
|
-
leftIcon: /*#__PURE__*/_react.default.createElement(_ffeIconsReact.Icon, {
|
|
140
|
-
fileUrl: downloadIcon,
|
|
141
|
-
size: "sm"
|
|
142
|
-
}),
|
|
143
|
-
onClick: this.triggerUploadFileNativeHandler,
|
|
144
|
-
id: "".concat(id, "-button")
|
|
145
|
-
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
146
|
-
id: "".concat(id, "-label")
|
|
147
|
-
}, label)), /*#__PURE__*/_react.default.createElement("div", {
|
|
148
|
-
className: "ffe-file-upload__upload-section-subtext"
|
|
149
|
-
}, uploadSubText))), /*#__PURE__*/_react.default.createElement("input", {
|
|
150
|
-
id: id,
|
|
151
|
-
type: "file",
|
|
152
|
-
multiple: multiple,
|
|
153
|
-
ref: this.setFileInputElement,
|
|
154
|
-
onChange: this.onFilesSelected,
|
|
155
|
-
"aria-labelledby": "".concat(id, "-label"),
|
|
156
|
-
accept: accept || '*'
|
|
157
|
-
}));
|
|
89
|
+
setIsHover(true);
|
|
90
|
+
},
|
|
91
|
+
onDragLeave: function onDragLeave() {
|
|
92
|
+
return setIsHover(false);
|
|
158
93
|
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
/** Title module */
|
|
189
|
-
title: _propTypes.string.isRequired,
|
|
190
|
-
/** Text on the info-section */
|
|
191
|
-
infoText: _propTypes.string.isRequired,
|
|
192
|
-
/** Subtext on the info-section */
|
|
193
|
-
infoSubText: _propTypes.string,
|
|
194
|
-
/** Label for the cancel button */
|
|
195
|
-
cancelText: _propTypes.string,
|
|
196
|
-
/** Label for the delete button */
|
|
197
|
-
deleteText: _propTypes.string,
|
|
198
|
-
/** Title on the upload-section */
|
|
199
|
-
uploadTitle: _propTypes.string.isRequired,
|
|
200
|
-
/** MicroText on the upload-section */
|
|
201
|
-
uploadMicroText: _propTypes.string.isRequired,
|
|
202
|
-
/** SubText on the upload-section */
|
|
203
|
-
uploadSubText: _propTypes.string.isRequired,
|
|
204
|
-
/** Unique file type specifier that describes a type of file that may be selected by the user, e.g. ".pdf"
|
|
205
|
-
* See MDN for documentation on
|
|
206
|
-
* [Unique file type specifiers](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers)
|
|
207
|
-
*/
|
|
208
|
-
accept: _propTypes.string
|
|
209
|
-
};
|
|
210
|
-
var _default = exports.default = FileUpload;
|
|
94
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
95
|
+
className: (0, _classnames.default)('ffe-file-upload__upload-section-border', {
|
|
96
|
+
'ffe-file-upload__upload-section-border--hover': isHover
|
|
97
|
+
})
|
|
98
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
99
|
+
className: "ffe-file-upload__upload-section-title"
|
|
100
|
+
}, uploadTitle), /*#__PURE__*/_react.default.createElement("div", {
|
|
101
|
+
className: "ffe-file-upload__upload-section-microtext"
|
|
102
|
+
}, uploadMicroText), /*#__PURE__*/_react.default.createElement(_ffeButtonsReact.SecondaryButton, {
|
|
103
|
+
leftIcon: /*#__PURE__*/_react.default.createElement(_ffeIconsReact.Icon, {
|
|
104
|
+
fileUrl: downloadIcon,
|
|
105
|
+
size: "sm"
|
|
106
|
+
}),
|
|
107
|
+
onClick: triggerUploadFileNativeHandler,
|
|
108
|
+
id: "".concat(id, "-button")
|
|
109
|
+
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
110
|
+
id: "".concat(id, "-label")
|
|
111
|
+
}, label)), /*#__PURE__*/_react.default.createElement("div", {
|
|
112
|
+
className: "ffe-file-upload__upload-section-subtext"
|
|
113
|
+
}, uploadSubText))), /*#__PURE__*/_react.default.createElement("input", {
|
|
114
|
+
id: id,
|
|
115
|
+
type: "file",
|
|
116
|
+
multiple: multiple,
|
|
117
|
+
ref: fileInputElement,
|
|
118
|
+
onChange: handleFileSelected,
|
|
119
|
+
"aria-labelledby": "".concat(id, "-label"),
|
|
120
|
+
accept: accept || '*'
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = _interopRequireDefault(require("react"));
|
|
4
|
+
var _sinon = require("sinon");
|
|
5
|
+
var _FileUpload = require("./FileUpload");
|
|
6
|
+
var _react2 = require("@testing-library/react");
|
|
7
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
8
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
9
|
+
var renderFileUpload = function renderFileUpload(props) {
|
|
10
|
+
return (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_FileUpload.FileUpload, _extends({
|
|
11
|
+
id: "file-upload",
|
|
12
|
+
label: "label",
|
|
13
|
+
title: "title",
|
|
14
|
+
infoText: "infoText",
|
|
15
|
+
uploadTitle: "uploadTitle",
|
|
16
|
+
uploadMicroText: "uploadMicroText",
|
|
17
|
+
uploadSubText: "uploadSubText",
|
|
18
|
+
files: {},
|
|
19
|
+
onFilesSelected: function onFilesSelected() {},
|
|
20
|
+
onFileDeleted: function onFileDeleted() {},
|
|
21
|
+
onFilesDropped: function onFilesDropped() {}
|
|
22
|
+
}, props)));
|
|
23
|
+
};
|
|
24
|
+
describe('<FileUpload/>', function () {
|
|
25
|
+
it('should have a button and input', function () {
|
|
26
|
+
var _renderFileUpload = renderFileUpload(),
|
|
27
|
+
container = _renderFileUpload.container;
|
|
28
|
+
expect(container.querySelector('#file-upload-button')).toBeTruthy();
|
|
29
|
+
expect(container.querySelector('#file-upload')).toBeTruthy();
|
|
30
|
+
});
|
|
31
|
+
it('should render input label', function () {
|
|
32
|
+
renderFileUpload();
|
|
33
|
+
expect(_react2.screen.getByRole('button', {
|
|
34
|
+
name: 'label'
|
|
35
|
+
})).toBeInTheDocument();
|
|
36
|
+
});
|
|
37
|
+
it('should extract and return files when user finishes selecting files', function () {
|
|
38
|
+
var onFilesSelected = (0, _sinon.spy)();
|
|
39
|
+
var _renderFileUpload2 = renderFileUpload({
|
|
40
|
+
onFilesSelected: onFilesSelected
|
|
41
|
+
}),
|
|
42
|
+
container = _renderFileUpload2.container;
|
|
43
|
+
var input = container.querySelector('input#file-upload');
|
|
44
|
+
_react2.fireEvent.change(input);
|
|
45
|
+
expect(onFilesSelected.calledOnce).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
it('should remove file from files when delete button is clicked', function () {
|
|
48
|
+
var onFileDeleted = (0, _sinon.spy)();
|
|
49
|
+
// Do click on span inside button with event listener instead of actual button to catch nested clicks.
|
|
50
|
+
var _renderFileUpload3 = renderFileUpload({
|
|
51
|
+
onFileDeleted: onFileDeleted,
|
|
52
|
+
files: {
|
|
53
|
+
fileToDelete: {
|
|
54
|
+
name: 'fileToDelete'
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
58
|
+
container = _renderFileUpload3.container;
|
|
59
|
+
var deleteButton = container.querySelector('.ffe-file-upload__file-item-delete-button-text');
|
|
60
|
+
_react2.fireEvent.click(deleteButton);
|
|
61
|
+
expect(onFileDeleted.calledWith({
|
|
62
|
+
name: 'fileToDelete'
|
|
63
|
+
})).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -8,7 +8,7 @@ var getFileContent = exports.getFileContent = function getFileContent(file) {
|
|
|
8
8
|
return new Promise(function (resolve, reject) {
|
|
9
9
|
var reader = new window.FileReader();
|
|
10
10
|
reader.onload = function (event) {
|
|
11
|
-
return resolve(event.target.result);
|
|
11
|
+
return resolve(event.target ? event.target.result : null);
|
|
12
12
|
};
|
|
13
13
|
reader.onerror = function (error) {
|
|
14
14
|
return reject(error);
|
package/lib/index.js
CHANGED
|
@@ -3,14 +3,23 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports
|
|
6
|
+
Object.defineProperty(exports, "FileUpload", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _FileUpload.FileUpload;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "FileUploadProps", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _FileUpload.FileUploadProps;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
7
18
|
Object.defineProperty(exports, "getFileContent", {
|
|
8
19
|
enumerable: true,
|
|
9
20
|
get: function get() {
|
|
10
|
-
return
|
|
21
|
+
return _getFileContent.getFileContent;
|
|
11
22
|
}
|
|
12
23
|
});
|
|
13
|
-
var _FileUpload =
|
|
14
|
-
var
|
|
15
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
-
var _default = exports.default = _FileUpload.default;
|
|
24
|
+
var _FileUpload = require("./FileUpload");
|
|
25
|
+
var _getFileContent = require("./getFileContent");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sb1/ffe-file-upload-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"description": "Upload file button with validation and list of uploaded files.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ffe"
|
|
@@ -23,22 +23,24 @@
|
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "ffe-buildtool babel",
|
|
25
25
|
"watch": "ffe-buildtool babel-watch",
|
|
26
|
-
"lint": "eslint src",
|
|
27
|
-
"lint:fix": "eslint src --fix",
|
|
26
|
+
"lint": "eslint src --ext ts,tsx",
|
|
27
|
+
"lint:fix": "eslint src --fix --ext ts,tsx",
|
|
28
28
|
"test": "ffe-buildtool jest",
|
|
29
29
|
"test:watch": "ffe-buildtool jest --watch"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@sb1/ffe-buttons-react": "^22.0.
|
|
32
|
+
"@sb1/ffe-buttons-react": "^22.0.5",
|
|
33
33
|
"@sb1/ffe-file-upload": "^10.0.39",
|
|
34
34
|
"@sb1/ffe-form": "^29.0.13",
|
|
35
|
-
"@sb1/ffe-icons-react": "^10.0.
|
|
35
|
+
"@sb1/ffe-icons-react": "^10.0.1",
|
|
36
36
|
"classnames": "^2.3.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@sb1/ffe-buildtool": "^0.6.1",
|
|
40
|
+
"@types/sinon": "^17.0.3",
|
|
40
41
|
"react": "^16.9.0",
|
|
41
|
-
"react-dom": "^16.9.0"
|
|
42
|
+
"react-dom": "^16.9.0",
|
|
43
|
+
"sinon": "^7.2.3"
|
|
42
44
|
},
|
|
43
45
|
"peerDependencies": {
|
|
44
46
|
"react": ">=16.9.0"
|
|
@@ -46,8 +48,5 @@
|
|
|
46
48
|
"publishConfig": {
|
|
47
49
|
"access": "public"
|
|
48
50
|
},
|
|
49
|
-
"
|
|
50
|
-
"prop-types": "^15.6.0"
|
|
51
|
-
},
|
|
52
|
-
"gitHead": "48bd1f6225acb09a6cf5f3c3e546b0abf9f59ef1"
|
|
51
|
+
"gitHead": "279a4e7d3afe4b4679448a28d1cdd8557740fdd5"
|
|
53
52
|
}
|
package/es/index.d.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
package/lib/index.d.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
-
var React = _interopRequireWildcard(require("react"));
|
|
5
|
-
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
6
|
-
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
package/types/index.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
export interface FileItem<T> {
|
|
4
|
-
name: string;
|
|
5
|
-
document?: T;
|
|
6
|
-
error?: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface FileUploadProps<T> {
|
|
10
|
-
id: string;
|
|
11
|
-
label: string;
|
|
12
|
-
files: Record<string, FileItem<T>>;
|
|
13
|
-
onFilesSelected(fileList: FileList): void;
|
|
14
|
-
onFilesDropped(fileList: FileList): void;
|
|
15
|
-
onFileDeleted(file: FileItem<T>): void;
|
|
16
|
-
multiple?: boolean;
|
|
17
|
-
title: string;
|
|
18
|
-
infoText: string;
|
|
19
|
-
infoSubText?: string;
|
|
20
|
-
cancelText?: string;
|
|
21
|
-
deleteText?: string;
|
|
22
|
-
uploadTitle: string;
|
|
23
|
-
uploadMicroText: string;
|
|
24
|
-
uploadSubText: string;
|
|
25
|
-
accept?: string;
|
|
26
|
-
}
|
|
27
|
-
declare class FileUpload<T> extends React.Component<FileUploadProps<T>, any> {}
|
|
28
|
-
|
|
29
|
-
declare function getFileContent(file: File): Promise<string>;
|
|
30
|
-
|
|
31
|
-
export default FileUpload;
|
|
32
|
-
export { getFileContent };
|