@cocreate/file 1.14.2 → 1.15.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
@@ -1,3 +1,17 @@
1
+ # [1.15.0](https://github.com/CoCreate-app/CoCreate-file/compare/v1.14.2...v1.15.0) (2024-02-05)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Removed https://cdn.cocreate.app/latest/CoCreate.min.css ([e0ae28d](https://github.com/CoCreate-app/CoCreate-file/commit/e0ae28de52a02ee58947093f6dad3dd9dfee93e8))
7
+ * renderValue ([4e3308a](https://github.com/CoCreate-app/CoCreate-file/commit/4e3308a157ee2257bc1eb603ddc1484b5579cac8))
8
+ * typo renderValue condition ([65ba50f](https://github.com/CoCreate-app/CoCreate-file/commit/65ba50fe6a84e02bad033f423d39a0ab22fdb766))
9
+
10
+
11
+ ### Features
12
+
13
+ * setValue() ([44d4012](https://github.com/CoCreate-app/CoCreate-file/commit/44d40127823d7ccdf8286943b435eeff939e6e2f))
14
+
1
15
  ## [1.14.2](https://github.com/CoCreate-app/CoCreate-file/compare/v1.14.1...v1.14.2) (2024-01-17)
2
16
 
3
17
 
package/demo/index.html CHANGED
@@ -32,10 +32,26 @@
32
32
  <button actions="upload">upload</button>
33
33
  </form>
34
34
 
35
+ <div
36
+ type="file"
37
+ array="test"
38
+ object=""
39
+ key="image"
40
+ accept="image/*"
41
+ placeholder="Upload Image or Video Thumbnail"
42
+ class="floating-label min-height:40px active"
43
+ render-selector="[template]"
44
+ active>
45
+ <div template>
46
+ <img src="{{image.src}}" alt="image" width="100%" />
47
+ </div>
48
+ </div>
49
+
35
50
  <form>
36
51
  <input
37
52
  type="file"
38
53
  directory
54
+ realtime="false"
39
55
  render-selector="document; [template]" />
40
56
 
41
57
  <button actions="saveLocally">saveLocally</button>
package/docs/index.html CHANGED
@@ -21,11 +21,6 @@
21
21
  property="og:image"
22
22
  content="https://cdn.cocreate.app/docs/file.png" />
23
23
 
24
- <!-- CoCreate CSS -->
25
- <link
26
- rel="stylesheet"
27
- href="https://cdn.cocreate.app/latest/CoCreate.min.css"
28
- type="text/css" />
29
24
  <link
30
25
  rel="stylesheet"
31
26
  href="../index.css"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/file",
3
- "version": "1.14.2",
3
+ "version": "1.15.0",
4
4
  "description": "A headless file uploader that uses HTML5 attributes for customization. Allows easy upload of files to server.",
5
5
  "keywords": [
6
6
  "file",
package/src/client.js CHANGED
@@ -26,7 +26,7 @@ import Observer from '@cocreate/observer';
26
26
  import Crud from '@cocreate/crud-client';
27
27
  import Elements from '@cocreate/elements';
28
28
  import Actions from '@cocreate/actions';
29
- import render from '@cocreate/render';
29
+ import { render } from '@cocreate/render';
30
30
  import { queryElements } from '@cocreate/utils';
31
31
  import '@cocreate/element-prototype';
32
32
 
@@ -42,38 +42,67 @@ const Files = new Map();
42
42
  * - If a single element is provided, it initializes that element (assuming it is of type "file").
43
43
  * - If an array of elements is provided, each element in the array is initialized.
44
44
  */
45
- function init(elements) {
45
+ async function init(elements) {
46
46
  if (!elements)
47
47
  elements = document.querySelectorAll('[type="file"]')
48
48
  else if (!Array.isArray(elements))
49
49
  elements = [elements]
50
50
  for (let i = 0; i < elements.length; i++) {
51
- if (elements[i].tagName !== 'INPUT') {
52
- // TODO: create input and append to div if input dos not exist
53
- // check if input exist
54
- let input = document.createElement("input");
55
- input.type = "file";
56
- input.setAttribute('hidden', '')
57
- elements[i].appendChild(input);
51
+ let nestedInput, isInput = elements[i].tagName === 'INPUT'
52
+ if (!isInput) {
53
+ nestedInput = elements[i].querySelector('input[type="file"]')
58
54
  }
59
55
 
60
56
  elements[i].getValue = async () => await getFiles([elements[i]])
61
57
  elements[i].getFiles = async () => await getFiles([elements[i]])
58
+ elements[i].setValue = (files) => setFiles(elements[i], files);
59
+ elements[i].renderValue = (files) => setFiles(elements[i], files);
62
60
 
63
- // elements[i].setValue = (value) => pickr.setColor(value);
61
+ // if (elements[i].renderValue) {
62
+ // let data = await elements[i].getValue()
63
+ // if (data)
64
+ // elements[i].setValue(data)
65
+ // }
64
66
 
65
67
  if (elements[i].hasAttribute('directory')) {
66
- if (window.showDirectoryPicker)
68
+ if (!isInput && window.showDirectoryPicker)
67
69
  elements[i].addEventListener("click", fileEvent);
68
70
  else if ('webkitdirectory' in elements[i]) {
69
71
  elements[i].webkitdirectory = true
70
- elements[i].addEventListener("change", fileEvent)
72
+ if (!isInput && !nestedInput) {
73
+ nestedInput = document.createElement("input");
74
+ nestedInput.type = "file";
75
+ nestedInput.setAttribute('hidden', '')
76
+ elements[i].appendChild(nestedInput);
77
+ }
78
+
79
+ if (nestedInput) {
80
+ elements[i].addEventListener("click", function () {
81
+ nestedInput.click()
82
+ });
83
+ nestedInput.addEventListener("change", fileEvent);
84
+ } else
85
+ elements[i].addEventListener("change", fileEvent);
71
86
  } else
72
87
  console.error("Directory selection not supported in this browser.");
73
- } else if (window.showOpenFilePicker)
88
+ } else if (!isInput && window.showOpenFilePicker)
74
89
  elements[i].addEventListener("click", fileEvent);
75
- else
76
- elements[i].addEventListener("change", fileEvent);
90
+ else {
91
+ if (!isInput && !nestedInput) {
92
+ nestedInput = document.createElement("input");
93
+ nestedInput.type = "file";
94
+ nestedInput.setAttribute('hidden', '')
95
+ elements[i].appendChild(nestedInput);
96
+ }
97
+
98
+ if (nestedInput) {
99
+ elements[i].addEventListener("click", function () {
100
+ nestedInput.click()
101
+ });
102
+ nestedInput.addEventListener("change", fileEvent);
103
+ } else
104
+ elements[i].addEventListener("change", fileEvent);
105
+ }
77
106
  }
78
107
  }
79
108
 
@@ -82,7 +111,7 @@ async function fileEvent(event) {
82
111
  const input = event.target;
83
112
  let selected = inputs.get(input) || new Map()
84
113
  let files = input.files;
85
- if (!files.length) {
114
+ if (!files || !files.length) {
86
115
  event.preventDefault()
87
116
  const multiple = input.multiple
88
117
  if (input.hasAttribute('directory')) {
@@ -120,7 +149,7 @@ async function fileEvent(event) {
120
149
  }
121
150
 
122
151
  if (!files[i].src)
123
- files[i] = await readFile(files[i])
152
+ await readFile(files[i])
124
153
 
125
154
  files[i].directory = handle.directory || '/'
126
155
  files[i].path = handle.path || '/'
@@ -140,15 +169,14 @@ async function fileEvent(event) {
140
169
  inputs.set(input, selected);
141
170
  console.log("Files selected:", selected);
142
171
 
143
- if (!input.renderValue)
144
- input.renderValue(selected.values())
172
+ if (input.renderValue)
173
+ input.renderValue(Array.from(selected.values()))
145
174
 
146
175
  const isImport = input.getAttribute('import')
147
176
  const isRealtime = input.getAttribute('realtime')
148
177
  if (isRealtime !== 'false' && (isImport || isImport == "")) {
149
178
  Import(input)
150
179
  }
151
-
152
180
  }
153
181
  } catch (error) {
154
182
  if (error.name !== 'AbortError') {
@@ -201,9 +229,9 @@ async function getFiles(fileInputs) {
201
229
  for (let input of fileInputs) {
202
230
  const selected = inputs.get(input)
203
231
  if (selected) {
204
- for (let file of selected.values()) {
232
+ for (let file of Array.from(selected.values())) {
205
233
  if (!file.src)
206
- file = await readFile(file)
234
+ await readFile(file)
207
235
 
208
236
  file = await getCustomData({ ...file })
209
237
  files.push(file)
@@ -214,7 +242,6 @@ async function getFiles(fileInputs) {
214
242
  return files
215
243
  }
216
244
 
217
- // gets file custom data
218
245
  async function getCustomData(file) {
219
246
  let form = document.querySelector(`[file_id="${file.id}"]`);
220
247
  if (form) {
@@ -226,10 +253,12 @@ async function getCustomData(file) {
226
253
  }
227
254
  }
228
255
  }
256
+
257
+ delete file.input;
258
+
229
259
  return file;
230
260
  }
231
261
 
232
-
233
262
  // This function reads the file and returns its src
234
263
  function readFile(file) {
235
264
  return new Promise((resolve) => {
@@ -244,7 +273,7 @@ function readFile(file) {
244
273
  } else if (['mp4', 'avi', 'mov', 'mpeg', 'flv'].includes(fileType[1])
245
274
  || fileType[0] === 'video') {
246
275
  readAs = 'readAsDataURL';
247
- } if (['mp3', 'wav', 'wma', 'aac', 'ogg'].includes(fileType[1])
276
+ } else if (['mp3', 'wav', 'wma', 'aac', 'ogg'].includes(fileType[1])
248
277
  || fileType[0] === 'audio') { // updated condition
249
278
  readAs = 'readAsDataURL';
250
279
  } else if (fileType[1] === 'pdf') {
@@ -269,6 +298,24 @@ function readFile(file) {
269
298
  });
270
299
  }
271
300
 
301
+ function setFiles(element, files) {
302
+ if (!files) return
303
+ if (!Array.isArray(files))
304
+ files = [files]
305
+ else if (!files.length)
306
+ return
307
+
308
+ let selected = inputs.get(element) || new Map()
309
+ for (let i = 0; i < files.length; i++) {
310
+ files[i].input = element
311
+ selected.set(files[i].id, files[i])
312
+ Files.set(files[i].id, files[i])
313
+ }
314
+ inputs.set(element, selected);
315
+ if (element.renderValue)
316
+ render({ source: element, data: Array.from(selected.values()) })
317
+ }
318
+
272
319
  async function save(element, action, data) {
273
320
  try {
274
321
  if (!data)