@umbraco-ui/uui-file-dropzone 1.8.0 → 1.9.0-rc.1

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.
@@ -10,6 +10,11 @@
10
10
  "description": "Comma-separated list of accepted mime types or file extensions (denoted with a `.`).\nIf this is left empty, it will allow all types.",
11
11
  "type": "string"
12
12
  },
13
+ {
14
+ "name": "disallow-folder-upload",
15
+ "type": "boolean",
16
+ "default": "false"
17
+ },
13
18
  {
14
19
  "name": "multiple",
15
20
  "description": "Allows for multiple files to be selected.",
@@ -29,6 +34,12 @@
29
34
  "description": "Comma-separated list of accepted mime types or file extensions (denoted with a `.`).\nIf this is left empty, it will allow all types.",
30
35
  "type": "string"
31
36
  },
37
+ {
38
+ "name": "disallowFolderUpload",
39
+ "attribute": "disallow-folder-upload",
40
+ "type": "boolean",
41
+ "default": "false"
42
+ },
32
43
  {
33
44
  "name": "multiple",
34
45
  "attribute": "multiple",
@@ -1,7 +1,8 @@
1
1
  import { UUIEvent } from '@umbraco-ui/uui-base/lib/events';
2
- import { UUIFileDropzoneElement } from './uui-file-dropzone.element';
2
+ import { UUIFileDropzoneElement, UUIFileFolder } from './uui-file-dropzone.element';
3
3
  export declare class UUIFileDropzoneEvent extends UUIEvent<{
4
4
  files: File[];
5
+ folders: UUIFileFolder[];
5
6
  }, UUIFileDropzoneElement> {
6
7
  static readonly CHANGE: string;
7
8
  constructor(evName: string, eventInit?: any | null);
package/lib/index.js CHANGED
@@ -3,7 +3,7 @@ import { LitElement, html, css } from 'lit';
3
3
  import { query, property } from 'lit/decorators.js';
4
4
  import { UUIEvent } from '@umbraco-ui/uui-base/lib/events';
5
5
  import { LabelMixin } from '@umbraco-ui/uui-base/lib/mixins';
6
- import { demandCustomElement } from '@umbraco-ui/uui-base/lib/utils';
6
+ import '@umbraco-ui/uui-symbol-file-dropzone/lib';
7
7
 
8
8
  class UUIFileDropzoneEvent extends UUIEvent {
9
9
  constructor(evName, eventInit = {}) {
@@ -22,8 +22,7 @@ var __decorateClass = (decorators, target, key, kind) => {
22
22
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
23
23
  if (decorator = decorators[i])
24
24
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
25
- if (kind && result)
26
- __defProp(target, key, result);
25
+ if (kind && result) __defProp(target, key, result);
27
26
  return result;
28
27
  };
29
28
  let UUIFileDropzoneElement = class extends LabelMixin("", LitElement) {
@@ -32,6 +31,7 @@ let UUIFileDropzoneElement = class extends LabelMixin("", LitElement) {
32
31
  this._acceptedFileExtensions = [];
33
32
  this._acceptedMimeTypes = [];
34
33
  this._accept = "";
34
+ this.disallowFolderUpload = false;
35
35
  this.multiple = false;
36
36
  this.addEventListener("dragenter", this._onDragEnter, false);
37
37
  this.addEventListener("dragleave", this._onDragLeave, false);
@@ -70,53 +70,74 @@ let UUIFileDropzoneElement = class extends LabelMixin("", LitElement) {
70
70
  browse() {
71
71
  this._input.click();
72
72
  }
73
- connectedCallback() {
74
- super.connectedCallback();
75
- demandCustomElement(this, "uui-symbol-file-dropzone");
76
- }
77
- async _getAllFileEntries(dataTransferItemList) {
78
- const fileEntries = [];
73
+ async _getAllEntries(dataTransferItemList) {
79
74
  const queue = [...dataTransferItemList];
80
- while (queue.length > 0) {
81
- const entry = queue.shift();
82
- if (entry.kind === "file") {
75
+ const folders = [];
76
+ const files = [];
77
+ for (const entry of queue) {
78
+ if (entry?.kind !== "file") continue;
79
+ if (entry.type) {
83
80
  const file = entry.getAsFile();
84
- if (!file)
85
- continue;
81
+ if (!file) continue;
86
82
  if (this._isAccepted(file)) {
87
- fileEntries.push(file);
83
+ files.push(file);
84
+ }
85
+ } else if (!this.disallowFolderUpload) {
86
+ const dir = this._getEntry(entry);
87
+ if (dir) {
88
+ const structure = await this._mkdir(dir);
89
+ folders.push(structure);
88
90
  }
89
- } else if (entry.kind === "directory") {
90
- if ("webkitGetAsEntry" in entry === false)
91
- continue;
92
- const directory = entry.webkitGetAsEntry();
93
- queue.push(
94
- ...await this._readAllDirectoryEntries(directory.createReader())
95
- );
96
91
  }
97
92
  }
98
- return fileEntries;
99
- }
100
- // Get all the entries (files or sub-directories) in a directory
101
- // by calling readEntries until it returns empty array
102
- async _readAllDirectoryEntries(directoryReader) {
103
- const entries = [];
104
- let readEntries = await this._readEntriesPromise(directoryReader);
105
- while (readEntries.length > 0) {
106
- entries.push(...readEntries);
107
- readEntries = await this._readEntriesPromise(directoryReader);
93
+ return { files, folders };
94
+ }
95
+ /**
96
+ * Get the directory entry from a DataTransferItem.
97
+ * @remark Supports both WebKit and non-WebKit browsers.
98
+ */
99
+ _getEntry(entry) {
100
+ let dir = null;
101
+ if ("webkitGetAsEntry" in entry) {
102
+ dir = entry.webkitGetAsEntry();
103
+ } else if ("getAsEntry" in entry) {
104
+ dir = entry.getAsEntry();
108
105
  }
109
- return entries;
110
- }
111
- async _readEntriesPromise(directoryReader) {
112
- return new Promise((resolve, reject) => {
113
- try {
114
- directoryReader.readEntries(resolve, reject);
115
- } catch (err) {
116
- console.log(err);
117
- reject(err);
118
- }
119
- });
106
+ return dir;
107
+ }
108
+ // Make directory structure
109
+ async _mkdir(entry) {
110
+ const reader = entry.createReader();
111
+ const folders = [];
112
+ const files = [];
113
+ const readEntries = (reader2) => {
114
+ return new Promise((resolve, reject) => {
115
+ reader2.readEntries(async (entries) => {
116
+ if (!entries.length) {
117
+ resolve();
118
+ return;
119
+ }
120
+ for (const en of entries) {
121
+ if (en.isFile) {
122
+ const file = await this._getAsFile(en);
123
+ if (this._isAccepted(file)) {
124
+ files.push(file);
125
+ }
126
+ } else if (en.isDirectory) {
127
+ const directory = await this._mkdir(
128
+ en
129
+ );
130
+ folders.push(directory);
131
+ }
132
+ }
133
+ readEntries(reader2);
134
+ resolve();
135
+ }, reject);
136
+ });
137
+ };
138
+ await readEntries(reader);
139
+ const result = { folderName: entry.name, folders, files };
140
+ return result;
120
141
  }
121
142
  _isAccepted(file) {
122
143
  if (this._acceptedFileExtensions.length === 0 && this._acceptedMimeTypes.length === 0) {
@@ -136,18 +157,22 @@ let UUIFileDropzoneElement = class extends LabelMixin("", LitElement) {
136
157
  }
137
158
  return false;
138
159
  }
160
+ async _getAsFile(fileEntry) {
161
+ return new Promise((resolve, reject) => fileEntry.file(resolve, reject));
162
+ }
139
163
  async _onDrop(e) {
140
164
  e.preventDefault();
141
165
  this._dropzone.classList.remove("hover");
142
166
  const items = e.dataTransfer?.items;
143
167
  if (items) {
144
- let result = await this._getAllFileEntries(items);
145
- if (this.multiple === false && result.length) {
146
- result = [result[0]];
168
+ const fileSystemResult = await this._getAllEntries(items);
169
+ if (this.multiple === false && fileSystemResult.files.length) {
170
+ fileSystemResult.files = [fileSystemResult.files[0]];
147
171
  }
172
+ this._getAllEntries(items);
148
173
  this.dispatchEvent(
149
174
  new UUIFileDropzoneEvent(UUIFileDropzoneEvent.CHANGE, {
150
- detail: { files: result }
175
+ detail: fileSystemResult
151
176
  })
152
177
  );
153
178
  }
@@ -239,6 +264,13 @@ __decorateClass([
239
264
  __decorateClass([
240
265
  property({ type: String })
241
266
  ], UUIFileDropzoneElement.prototype, "accept", 1);
267
+ __decorateClass([
268
+ property({
269
+ type: Boolean,
270
+ reflect: true,
271
+ attribute: "disallow-folder-upload"
272
+ })
273
+ ], UUIFileDropzoneElement.prototype, "disallowFolderUpload", 2);
242
274
  __decorateClass([
243
275
  property({ type: Boolean })
244
276
  ], UUIFileDropzoneElement.prototype, "multiple", 2);
@@ -1,4 +1,10 @@
1
1
  import { LitElement } from 'lit';
2
+ import '@umbraco-ui/uui-symbol-file-dropzone/lib';
3
+ export interface UUIFileFolder {
4
+ folderName: string;
5
+ folders: UUIFileFolder[];
6
+ files: File[];
7
+ }
2
8
  declare const UUIFileDropzoneElement_base: (new (...args: any[]) => import("@umbraco-ui/uui-base/lib/mixins").LabelMixinInterface) & typeof LitElement;
3
9
  /**
4
10
  * @element uui-file-dropzone
@@ -25,6 +31,7 @@ export declare class UUIFileDropzoneElement extends UUIFileDropzoneElement_base
25
31
  */
26
32
  set accept(value: string);
27
33
  get accept(): string;
34
+ disallowFolderUpload: boolean;
28
35
  /**
29
36
  * Allows for multiple files to be selected.
30
37
  * @type {boolean}
@@ -38,11 +45,15 @@ export declare class UUIFileDropzoneElement extends UUIFileDropzoneElement_base
38
45
  */
39
46
  browse(): void;
40
47
  constructor();
41
- connectedCallback(): void;
42
- private _getAllFileEntries;
43
- private _readAllDirectoryEntries;
44
- private _readEntriesPromise;
48
+ private _getAllEntries;
49
+ /**
50
+ * Get the directory entry from a DataTransferItem.
51
+ * @remark Supports both WebKit and non-WebKit browsers.
52
+ */
53
+ private _getEntry;
54
+ private _mkdir;
45
55
  private _isAccepted;
56
+ private _getAsFile;
46
57
  private _onDrop;
47
58
  private _onDragOver;
48
59
  private _onDragEnter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umbraco-ui/uui-file-dropzone",
3
- "version": "1.8.0",
3
+ "version": "1.9.0-rc.1",
4
4
  "license": "MIT",
5
5
  "keywords": [
6
6
  "Umbraco",
@@ -30,8 +30,8 @@
30
30
  "custom-elements.json"
31
31
  ],
32
32
  "dependencies": {
33
- "@umbraco-ui/uui-base": "1.8.0",
34
- "@umbraco-ui/uui-symbol-file-dropzone": "1.8.0"
33
+ "@umbraco-ui/uui-base": "1.9.0-rc.1",
34
+ "@umbraco-ui/uui-symbol-file-dropzone": "1.9.0-rc.1"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "npm run analyze && tsc --build && rollup -c rollup.config.js",
@@ -42,5 +42,5 @@
42
42
  "access": "public"
43
43
  },
44
44
  "homepage": "https://uui.umbraco.com/?path=/story/uui-file-dropzone",
45
- "gitHead": "53021762a52dc54a46f0c5ef829c1cbaabde1160"
45
+ "gitHead": "7092b4717d8b9d4825b15e087508b8f75bf81a92"
46
46
  }