@instructure/ui-file-drop 8.25.1-snapshot.0 → 8.26.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/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [8.26.0](https://github.com/instructure/instructure-ui/compare/v8.25.0...v8.26.0) (2022-06-30)
7
+
8
+ **Note:** Version bump only for package @instructure/ui-file-drop
9
+
6
10
  # [8.25.0](https://github.com/instructure/instructure-ui/compare/v8.24.5...v8.25.0) (2022-06-03)
7
11
 
8
12
  **Note:** Version bump only for package @instructure/ui-file-drop
@@ -29,13 +29,12 @@ var _dec, _dec2, _dec3, _class, _class2;
29
29
  */
30
30
 
31
31
  /** @jsx jsx */
32
- import { Component } from 'react';
32
+ import React, { Component } from 'react';
33
33
  import keycode from 'keycode';
34
34
  import { FormFieldMessages } from '@instructure/ui-form-field';
35
35
  import { View } from '@instructure/ui-view';
36
36
  import { testable } from '@instructure/ui-testable';
37
37
  import { callRenderProp, passthroughProps, getInteraction, withDeterministicId } from '@instructure/ui-react-utils';
38
- import { isEdge } from '@instructure/ui-utils';
39
38
  import { accepts, getAcceptList } from './utils/accepts';
40
39
  import { getEventFiles } from './utils/getEventFiles';
41
40
  import { withStyle, jsx } from '@instructure/emotion';
@@ -45,27 +44,15 @@ import { propTypes, allowedProps } from './props';
45
44
 
46
45
  function keyEventIsClickButton(e) {
47
46
  return e.keyCode === keycode.codes.space || e.keyCode === keycode.codes.enter;
48
- } // Used try-catch due to missing document/navigator references in Jenkins
49
-
50
-
51
- function isBrowserMS() {
52
- let result = false;
53
-
54
- try {
55
- result = document.documentMode || isEdge;
56
- } catch (e) {} // eslint-disable-line no-empty
57
-
58
-
59
- return result;
60
47
  }
61
-
62
- const IS_MS = isBrowserMS();
63
48
  /**
64
49
  ---
65
50
  category: components
66
51
  ---
52
+ @tsProps
67
53
  **/
68
54
 
55
+
69
56
  let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, generateComponentTheme), _dec3 = testable(), _dec(_class = _dec2(_class = _dec3(_class = (_class2 = class FileDrop extends Component {
70
57
  constructor(props) {
71
58
  super(props);
@@ -96,6 +83,8 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
96
83
  };
97
84
 
98
85
  this.handleDragEnter = e => {
86
+ var _this$props$onDragEnt, _this$props;
87
+
99
88
  e.preventDefault(); // Count the dropzone and any children that are entered.
100
89
 
101
90
  this.enterCounter += 1; // Don't trigger onDragEnter for each children after the first one
@@ -109,10 +98,12 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
109
98
  isDragAccepted: allFilesAccepted,
110
99
  isDragRejected: !allFilesAccepted
111
100
  });
112
- this.props.onDragEnter(e);
101
+ (_this$props$onDragEnt = (_this$props = this.props).onDragEnter) === null || _this$props$onDragEnt === void 0 ? void 0 : _this$props$onDragEnt.call(_this$props, e);
113
102
  };
114
103
 
115
104
  this.handleDragOver = e => {
105
+ var _this$props$onDragOve, _this$props2;
106
+
116
107
  e.preventDefault();
117
108
  e.stopPropagation();
118
109
 
@@ -122,12 +113,13 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
122
113
  } catch (err) {// continue regardless of error
123
114
  }
124
115
 
125
- ;
126
- this.props.onDragOver(e);
116
+ (_this$props$onDragOve = (_this$props2 = this.props).onDragOver) === null || _this$props$onDragOve === void 0 ? void 0 : _this$props$onDragOve.call(_this$props2, e);
127
117
  return false;
128
118
  };
129
119
 
130
120
  this.handleDragLeave = e => {
121
+ var _this$props$onDragLea, _this$props3;
122
+
131
123
  e.preventDefault();
132
124
  this.enterCounter -= 1; // Only deactivate once the dropzone and all children was left
133
125
 
@@ -139,15 +131,15 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
139
131
  isDragAccepted: false,
140
132
  isDragRejected: false
141
133
  });
142
- this.props.onDragLeave(e);
134
+ (_this$props$onDragLea = (_this$props3 = this.props).onDragLeave) === null || _this$props$onDragLea === void 0 ? void 0 : _this$props$onDragLea.call(_this$props3, e);
143
135
  };
144
136
 
145
137
  this.handleChange = e => {
146
- const _this$props = this.props,
147
- onDrop = _this$props.onDrop,
148
- onDropAccepted = _this$props.onDropAccepted,
149
- onDropRejected = _this$props.onDropRejected,
150
- shouldEnablePreview = _this$props.shouldEnablePreview;
138
+ const _this$props4 = this.props,
139
+ onDrop = _this$props4.onDrop,
140
+ onDropAccepted = _this$props4.onDropAccepted,
141
+ onDropRejected = _this$props4.onDropRejected,
142
+ shouldEnablePreview = _this$props4.shouldEnablePreview;
151
143
  const fileList = this.getDataTransferItems(e, shouldEnablePreview);
152
144
 
153
145
  const _this$parseFiles = this.parseFiles(fileList),
@@ -157,13 +149,13 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
157
149
 
158
150
  e.preventDefault();
159
151
  this.enterCounter = 0;
160
- onDrop(accepted, rejected, e);
152
+ onDrop && onDrop(accepted, rejected, e);
161
153
 
162
- if (rejected.length > 0) {
154
+ if (rejected.length > 0 && onDropRejected) {
163
155
  onDropRejected(rejected, e);
164
156
  }
165
157
 
166
- if (accepted.length > 0) {
158
+ if (accepted.length > 0 && onDropAccepted) {
167
159
  onDropAccepted(accepted, e);
168
160
  }
169
161
 
@@ -175,7 +167,7 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
175
167
  };
176
168
 
177
169
  this.fileAccepted = file => {
178
- return accepts(file, this.props.accept);
170
+ if (this.props.accept) return accepts(file, this.props.accept);else return true;
179
171
  };
180
172
 
181
173
  this.handleRef = el => {
@@ -197,12 +189,14 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
197
189
  };
198
190
 
199
191
  this.handleClick = e => {
192
+ var _this$fileInputEl;
193
+
200
194
  if (this.fileInputEl.value && this.props.shouldAllowRepeats) {
201
195
  this.fileInputEl.value = null;
202
196
  } // focus the input (because FF won't)
203
197
 
204
198
 
205
- this.fileInputEl.focus();
199
+ (_this$fileInputEl = this.fileInputEl) === null || _this$fileInputEl === void 0 ? void 0 : _this$fileInputEl.focus();
206
200
  this.props.onClick(e);
207
201
  this.setState({
208
202
  isFileBrowserDisplayed: true
@@ -213,16 +207,6 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
213
207
  if (this.state.isFocused && keyEventIsClickButton(e)) {
214
208
  if (this.props.shouldAllowRepeats) {
215
209
  this.fileInputEl.value = null;
216
- } // This bit of logic is necessary for MS browsers but causes unwanted warnings in Firefox
217
- // So we need to apply this logic only on MS browsers
218
-
219
- /* istanbul ignore if */
220
-
221
-
222
- if (IS_MS) {
223
- e.stopPropagation();
224
- e.preventDefault();
225
- this.fileInputEl.click();
226
210
  }
227
211
  }
228
212
  };
@@ -244,13 +228,19 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
244
228
  }
245
229
 
246
230
  componentDidMount() {
247
- ;
248
- this.props.makeStyles(this.makeStyleProps());
231
+ var _this$props$makeStyle, _this$props5;
232
+
233
+ (_this$props$makeStyle = (_this$props5 = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props5, this.makeStyleProps());
249
234
  }
250
235
 
251
236
  componentDidUpdate() {
252
- ;
253
- this.props.makeStyles(this.makeStyleProps());
237
+ var _this$props$makeStyle2, _this$props6;
238
+
239
+ (_this$props$makeStyle2 = (_this$props6 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props6, this.makeStyleProps());
240
+ }
241
+
242
+ convertToFile(fileLikeItem) {
243
+ if (fileLikeItem instanceof DataTransferItem) return fileLikeItem.getAsFile();else return fileLikeItem;
254
244
  }
255
245
 
256
246
  get functionallyDisabled() {
@@ -274,7 +264,11 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
274
264
  }
275
265
 
276
266
  getDataTransferItems(e, shouldEnablePreview) {
277
- let list = Array.from(getEventFiles(e, this.fileInputEl));
267
+ let list = [];
268
+ Array.from(getEventFiles(e, this.fileInputEl)).forEach(file => {
269
+ const fileObj = this.convertToFile(file);
270
+ if (fileObj) list.push(fileObj);
271
+ });
278
272
 
279
273
  if (list.length > 1) {
280
274
  list = this.props.shouldAllowMultiple ? list : [list[0]];
@@ -293,7 +287,9 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
293
287
  const accepted = [];
294
288
  const rejected = [];
295
289
  fileList.forEach(file => {
296
- if (this.fileAccepted(file) && this.fileMatchSize(file)) {
290
+ const fileObj = this.convertToFile(file);
291
+
292
+ if (fileObj && this.fileAccepted(fileObj) && this.fileMatchSize(fileObj)) {
297
293
  accepted.push(file);
298
294
  } else {
299
295
  rejected.push(file);
@@ -312,7 +308,7 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
312
308
 
313
309
  acceptStr() {
314
310
  const accept = this.props.accept;
315
- return accept ? getAcceptList(accept).join(',') : null;
311
+ return accept ? getAcceptList(accept).join(',') : void 0;
316
312
  }
317
313
 
318
314
  renderLabel() {
@@ -325,16 +321,18 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
325
321
  }
326
322
 
327
323
  render() {
328
- const _this$props2 = this.props,
329
- display = _this$props2.display,
330
- height = _this$props2.height,
331
- width = _this$props2.width,
332
- minWidth = _this$props2.minWidth,
333
- maxWidth = _this$props2.maxWidth,
334
- margin = _this$props2.margin,
335
- onDropAccepted = _this$props2.onDropAccepted,
336
- onDropRejected = _this$props2.onDropRejected,
337
- props = _objectWithoutProperties(_this$props2, _excluded);
324
+ var _this$props$styles, _this$props$styles2, _this$props$styles3, _this$props$styles4;
325
+
326
+ const _this$props7 = this.props,
327
+ display = _this$props7.display,
328
+ height = _this$props7.height,
329
+ width = _this$props7.width,
330
+ minWidth = _this$props7.minWidth,
331
+ maxWidth = _this$props7.maxWidth,
332
+ margin = _this$props7.margin,
333
+ onDropAccepted = _this$props7.onDropAccepted,
334
+ onDropRejected = _this$props7.onDropRejected,
335
+ props = _objectWithoutProperties(_this$props7, _excluded);
338
336
 
339
337
  const id = this.props.id || this.defaultId;
340
338
  const focusColor = this.state.isDragRejected || this.invalid ? 'danger' : void 0;
@@ -349,7 +347,7 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
349
347
  height: height,
350
348
  elementRef: this.handleElementRef
351
349
  }, jsx("label", {
352
- css: this.props.styles.fileDropLabel,
350
+ css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.fileDropLabel,
353
351
  htmlFor: id,
354
352
  onDragEnter: this.handleDragEnter,
355
353
  onDragOver: this.handleDragOver,
@@ -363,15 +361,15 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
363
361
  focusColor: focusColor,
364
362
  height: height
365
363
  }, jsx("span", {
366
- css: this.props.styles.fileDropLabelContent
364
+ css: (_this$props$styles2 = this.props.styles) === null || _this$props$styles2 === void 0 ? void 0 : _this$props$styles2.fileDropLabelContent
367
365
  }, jsx("span", {
368
- css: this.props.styles.fileDropLayout
366
+ css: (_this$props$styles3 = this.props.styles) === null || _this$props$styles3 === void 0 ? void 0 : _this$props$styles3.fileDropLayout
369
367
  }, jsx(View, {
370
368
  height: height
371
369
  }, this.renderLabel()))))), jsx("input", Object.assign({}, passthroughProps(props), {
372
370
  onClick: this.handleClick,
373
371
  type: "file",
374
- css: this.props.styles.fileDropInput,
372
+ css: (_this$props$styles4 = this.props.styles) === null || _this$props$styles4 === void 0 ? void 0 : _this$props$styles4.fileDropInput,
375
373
  id: id,
376
374
  ref: this.handleRef,
377
375
  onFocus: this.handleFocus,
@@ -381,7 +379,7 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
381
379
  multiple: this.props.shouldAllowMultiple,
382
380
  accept: this.acceptStr(),
383
381
  onChange: this.handleChange,
384
- "aria-describedby": this.hasMessages ? this.messagesId : null,
382
+ "aria-describedby": this.hasMessages ? this.messagesId : void 0,
385
383
  disabled: this.functionallyDisabled
386
384
  })), this.hasMessages ? jsx(View, {
387
385
  display: "block",
@@ -393,13 +391,7 @@ let FileDrop = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, g
393
391
  }
394
392
 
395
393
  }, _class2.displayName = "FileDrop", _class2.componentId = 'FileDrop', _class2.propTypes = propTypes, _class2.allowedProps = allowedProps, _class2.defaultProps = {
396
- onClick: function (e) {},
397
- onDrop: function (accepted, rejected, e) {},
398
- onDropAccepted: function (accepted, e) {},
399
- onDropRejected: function (rejected, e) {},
400
- onDragEnter: function (e) {},
401
- onDragOver: function (e) {},
402
- onDragLeave: function (e) {},
394
+ onClick: function (_e) {},
403
395
  shouldEnablePreview: false,
404
396
  shouldAllowMultiple: false,
405
397
  shouldAllowRepeats: true,
@@ -25,126 +25,28 @@ import PropTypes from 'prop-types';
25
25
  import { FormPropTypes } from '@instructure/ui-form-field';
26
26
  import { ThemeablePropTypes } from '@instructure/emotion';
27
27
  const propTypes = {
28
- /**
29
- * The id of the input (to link it to its label for a11y)
30
- */
31
28
  id: PropTypes.string,
32
-
33
- /**
34
- * The content of FileDrop; can be a component or React node.
35
- * Components receive `isDragAccepted` and `isDragRejected` as props.
36
- */
37
29
  renderLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired,
38
-
39
- /**
40
- * The mime media type/s or file extension/s allowed to be dropped inside
41
- */
42
30
  accept: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
43
-
44
- /**
45
- * object with shape: `{
46
- * text: PropTypes.node,
47
- * type: PropTypes.oneOf(['error', 'hint', 'success', 'screenreader-only'])
48
- * }`
49
- */
50
31
  messages: PropTypes.arrayOf(FormPropTypes.message),
51
-
52
- /**
53
- * Called when clicking on drop area to select files to upload
54
- */
55
32
  onClick: PropTypes.func,
56
-
57
- /**
58
- * Called when dropping files or when file dialog window exits successfully
59
- */
60
33
  onDrop: PropTypes.func,
61
-
62
- /**
63
- * Called when dropping allowed files
64
- */
65
34
  onDropAccepted: PropTypes.func,
66
-
67
- /**
68
- * Called when dropping rejected files
69
- */
70
35
  onDropRejected: PropTypes.func,
71
-
72
- /**
73
- * Called when dragging files
74
- * and passing through FileDrop's content for the first time
75
- */
76
36
  onDragEnter: PropTypes.func,
77
-
78
- /**
79
- * Called when dragging files and passing through FileDrop's content
80
- */
81
37
  onDragOver: PropTypes.func,
82
-
83
- /**
84
- * Called when dragging files and leaving FileDrop's content
85
- */
86
38
  onDragLeave: PropTypes.func,
87
-
88
- /**
89
- * Flag to use window.URL.createObjectURL for each dropped file and pass it through file.preview
90
- */
91
39
  shouldEnablePreview: PropTypes.bool,
92
-
93
- /**
94
- * Flag to allow multiple files to drop at once
95
- */
96
40
  shouldAllowMultiple: PropTypes.bool,
97
-
98
- /**
99
- * Flag to allow upload of the same file more than once
100
- */
101
41
  shouldAllowRepeats: PropTypes.bool,
102
-
103
- /**
104
- * the maximum file size allowed
105
- */
106
42
  maxSize: PropTypes.number,
107
-
108
- /**
109
- * the minimum file size allowed
110
- */
111
43
  minSize: PropTypes.number,
112
-
113
- /**
114
- * Specifies if interaction with the input is enabled, disabled, or readonly.
115
- */
116
44
  interaction: PropTypes.oneOf(['enabled', 'disabled', 'readonly']),
117
-
118
- /**
119
- * Set the CSS `display` property on FileInput's outermost element
120
- */
121
45
  display: PropTypes.oneOf(['block', 'inline-block']),
122
-
123
- /**
124
- * Set the CSS `height` property on FileInput's outermost element
125
- */
126
46
  height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
127
-
128
- /**
129
- * Set the CSS `width` property on FileInput's outermost element
130
- */
131
47
  width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
132
-
133
- /**
134
- * Set the CSS `maxWidth` property on FileInput's outermost element
135
- */
136
48
  maxWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
137
-
138
- /**
139
- * Set the CSS `minWidth` property on FileInput's outermost element
140
- */
141
49
  minWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
142
-
143
- /**
144
- * Valid values are 0, none, auto, xxx-small, xx-small, x-small, small,
145
- * medium, large, x-large, xx-large. Apply these values via familiar
146
- * CSS-like shorthand. For example: margin="small auto large".
147
- */
148
50
  margin: ThemeablePropTypes.spacing
149
51
  };
150
52
  const allowedProps = ['id', 'renderLabel', 'accept', 'messages', 'onClick', 'onDrop', 'onDropAccepted', 'onDropRejected', 'onDragEnter', 'onDragOver', 'onDragLeave', 'shouldEnablePreview', 'shouldAllowMultiple', 'shouldAllowRepeats', 'maxSize', 'minSize', 'interaction', 'display', 'height', 'width', 'maxWidth', 'minWidth', 'margin'];
@@ -22,13 +22,15 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
  function getEventFiles(event, inputEl) {
25
- const dt = event.dataTransfer;
25
+ if ('dataTransfer' in event) {
26
+ const dt = event.dataTransfer;
26
27
 
27
- if (dt) {
28
- if (dt.files && dt.files.length) {
29
- return dt.files;
30
- } else if (dt.items && dt.items.length) {
31
- return dt.items;
28
+ if (dt) {
29
+ if (dt.files && dt.files.length) {
30
+ return dt.files;
31
+ } else if (dt.items && dt.items.length) {
32
+ return dt.items;
33
+ }
32
34
  }
33
35
  } else if (inputEl && inputEl.files) {
34
36
  return inputEl.files;