wx-svelte-uploader 1.3.0 → 2.0.0-beta-2
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/package.json +25 -6
- package/readme.md +39 -25
- package/src/components/Uploader.svelte +47 -26
- package/src/components/UploaderList.svelte +19 -16
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wx-svelte-uploader",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta-2",
|
|
4
|
+
"description": "A Svelte UI component for easy and intuitive file upload",
|
|
4
5
|
"productTag": "uploader",
|
|
5
6
|
"productTrial": false,
|
|
6
7
|
"type": "module",
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
"build:dist": "vite build --mode dist",
|
|
10
11
|
"build:tests": "vite build --mode test",
|
|
11
12
|
"lint": "yarn eslint ./demos ./src --ext .svelte,.ts,.js",
|
|
12
|
-
"start": "vite --open
|
|
13
|
+
"start": "vite --open",
|
|
13
14
|
"start:tests": "vite --open=/tests/ --host 0.0.0.0 --port 5100 --mode test",
|
|
14
15
|
"test": "true",
|
|
15
16
|
"test:cypress": "cypress run -P ./ --config \"baseUrl=http://localhost:5100/tests\""
|
|
@@ -22,16 +23,34 @@
|
|
|
22
23
|
"./package.json": "./package.json"
|
|
23
24
|
},
|
|
24
25
|
"license": "MIT",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/svar-widgets/uploader.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://forum.svar.dev"
|
|
27
32
|
},
|
|
28
|
-
"
|
|
29
|
-
|
|
33
|
+
"homepage": "https://svar.dev/svelte/core/",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"wx-svelte-core": "2.0.0-beta-2",
|
|
36
|
+
"wx-lib-dom": "0.6.0"
|
|
30
37
|
},
|
|
31
38
|
"files": [
|
|
32
39
|
"src",
|
|
33
40
|
"readme.md",
|
|
34
41
|
"whatsnew.md",
|
|
35
42
|
"license.txt"
|
|
43
|
+
],
|
|
44
|
+
"keywords": [
|
|
45
|
+
"svelte",
|
|
46
|
+
"svar widgets",
|
|
47
|
+
"upload",
|
|
48
|
+
"uploader",
|
|
49
|
+
"file uploader",
|
|
50
|
+
"svelte uploader",
|
|
51
|
+
"svelte component",
|
|
52
|
+
"ui component",
|
|
53
|
+
"svelte file uploader",
|
|
54
|
+
"fileuploader"
|
|
36
55
|
]
|
|
37
56
|
}
|
package/readme.md
CHANGED
|
@@ -1,38 +1,52 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# SVAR Svelte File Uploader
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/wx-svelte-uploader)
|
|
6
|
+
[](https://github.com/svar-widgets/uploader/blob/main/license.txt)
|
|
7
|
+
[](https://www.npmjs.com/package/wx-svelte-uploader)
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
<script>
|
|
7
|
-
import { Uploader } from 'wx-svelte-uploader';
|
|
8
|
-
</script>
|
|
9
|
+
</div>
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
A Svelte UI component for easy and intuitive file uploading, allowing users to drag and drop files or select them from their device.
|
|
12
|
+
See the demos [here](https://docs.svar.dev/svelte/core/samples-uploader).
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
### How to Use
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
To use the widget, simply import the package and include the component in your Svelte file:
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
the dev server will start at http://localhost:5100/tests.html
|
|
18
|
+
```svelte
|
|
19
|
+
<script>
|
|
20
|
+
import { Uploader, UploaderList } from "wx-svelte-uploader";
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
let data = [];
|
|
23
|
+
const uploadURL = "http://localhost:3000/data";
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
function handleUpload(ev) {
|
|
26
|
+
console.log(ev.detail);
|
|
27
|
+
}
|
|
28
|
+
</script>
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
cypress run -P ./ --config "baseUrl=http://localhost:5100"
|
|
30
|
+
<UploaderList bind:data />
|
|
31
|
+
<Uploader {uploadURL} bind:data on:upload={handleUpload} />
|
|
29
32
|
```
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
### How to Modify
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
Typically, you don't need to modify the code. However, if you wish to do so, follow these steps:
|
|
37
|
+
|
|
38
|
+
1. Run `yarn` to install dependencies. Note that this project is a monorepo using `yarn` workspaces, so npm will not work
|
|
39
|
+
2. Start the project in development mode with `yarn start`
|
|
40
|
+
|
|
41
|
+
### Run Tests
|
|
42
|
+
|
|
43
|
+
To run the test:
|
|
37
44
|
|
|
38
|
-
|
|
45
|
+
1. Start the test examples with:
|
|
46
|
+
```sh
|
|
47
|
+
yarn start:tests
|
|
48
|
+
```
|
|
49
|
+
2. In a separate console, run the end-to-end tests with:
|
|
50
|
+
```sh
|
|
51
|
+
yarn test:cypress
|
|
52
|
+
```
|
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { uid } from "wx-lib-dom";
|
|
3
|
-
import { onMount,
|
|
3
|
+
import { onMount, setContext } from "svelte";
|
|
4
4
|
import { apiKey } from "../helpers/consts";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
let {
|
|
7
|
+
data = $bindable([]),
|
|
8
|
+
ready = $bindable(new Promise(() => ({}))),
|
|
9
|
+
|
|
10
|
+
accept = "",
|
|
11
|
+
multiple = true,
|
|
12
|
+
folder = false,
|
|
13
|
+
uploadURL = "",
|
|
14
|
+
apiOnly = false,
|
|
15
|
+
disabled = false,
|
|
16
|
+
children,
|
|
17
|
+
onchange,
|
|
18
|
+
onupload,
|
|
19
|
+
} = $props();
|
|
20
|
+
|
|
21
|
+
let input = $state();
|
|
22
|
+
let drag = $state();
|
|
20
23
|
let count = 0;
|
|
21
24
|
let lastCtx = {};
|
|
22
25
|
|
|
23
26
|
const api = {
|
|
24
27
|
open: ctx => open(ctx),
|
|
28
|
+
getState: () => getState(),
|
|
25
29
|
droparea: (node, ctx) => {
|
|
26
30
|
if (disabled) return;
|
|
27
31
|
|
|
@@ -98,7 +102,7 @@
|
|
|
98
102
|
};
|
|
99
103
|
|
|
100
104
|
if (obj.selected) obj.selected(obj);
|
|
101
|
-
|
|
105
|
+
onchange && onchange(obj);
|
|
102
106
|
|
|
103
107
|
if (multiple) {
|
|
104
108
|
data = [...data, obj];
|
|
@@ -146,13 +150,28 @@
|
|
|
146
150
|
});
|
|
147
151
|
}
|
|
148
152
|
|
|
153
|
+
// returns client if any file is being uploaded
|
|
154
|
+
// returns error if any file has failed and no file is being uploaded
|
|
155
|
+
// returns server if all files have been uploaded
|
|
156
|
+
function getState() {
|
|
157
|
+
let status = "server";
|
|
158
|
+
for (let i = 0; i < data.length; i++) {
|
|
159
|
+
if (data[i].status === "client") return "client";
|
|
160
|
+
if (data[i].status === "error") status = "error";
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return status;
|
|
164
|
+
}
|
|
165
|
+
|
|
149
166
|
function updateData(id, result) {
|
|
150
167
|
const ind = data.findIndex(i => i.id == id);
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
168
|
+
const file = (data[ind] = { ...data[ind], ...result });
|
|
169
|
+
|
|
170
|
+
const res = { file, status: getState() };
|
|
171
|
+
if (file && file.uploaded) file.uploaded(res);
|
|
172
|
+
onupload && onupload(res);
|
|
154
173
|
|
|
155
|
-
if (
|
|
174
|
+
if (file.temp) data = data.filter(i => i.id != id);
|
|
156
175
|
}
|
|
157
176
|
|
|
158
177
|
function dragenter() {
|
|
@@ -176,12 +195,12 @@
|
|
|
176
195
|
type="file"
|
|
177
196
|
class="input"
|
|
178
197
|
bind:this={input}
|
|
179
|
-
|
|
198
|
+
onchange={add}
|
|
180
199
|
{accept}
|
|
181
200
|
{multiple}
|
|
182
201
|
{disabled}
|
|
183
202
|
/>
|
|
184
|
-
|
|
203
|
+
{@render children?.()}
|
|
185
204
|
{:else}
|
|
186
205
|
<div
|
|
187
206
|
class="label"
|
|
@@ -193,19 +212,21 @@
|
|
|
193
212
|
type="file"
|
|
194
213
|
class="input"
|
|
195
214
|
bind:this={input}
|
|
196
|
-
|
|
215
|
+
onchange={add}
|
|
197
216
|
{accept}
|
|
198
217
|
{multiple}
|
|
199
218
|
{disabled}
|
|
200
219
|
/>
|
|
201
|
-
|
|
220
|
+
{#if children}{@render children({ open })}{:else}
|
|
202
221
|
<div class="dropzone">
|
|
203
222
|
<span>
|
|
204
223
|
Drop files here or
|
|
205
|
-
|
|
224
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
225
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
226
|
+
<span class="action" onclick={open}>select files</span>
|
|
206
227
|
</span>
|
|
207
228
|
</div>
|
|
208
|
-
|
|
229
|
+
{/if}
|
|
209
230
|
</div>
|
|
210
231
|
{/if}
|
|
211
232
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
2
|
+
let { data = $bindable([]) } = $props();
|
|
3
3
|
|
|
4
4
|
const fileSize = ["b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb"];
|
|
5
5
|
|
|
@@ -19,35 +19,42 @@
|
|
|
19
19
|
}
|
|
20
20
|
return Math.round(size * 100) / 100 + " " + fileSize[index];
|
|
21
21
|
}
|
|
22
|
-
|
|
23
22
|
</script>
|
|
24
23
|
|
|
25
24
|
{#if data.length}
|
|
26
25
|
<div class="layout">
|
|
27
26
|
<div class="header">
|
|
28
|
-
|
|
27
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
28
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
29
|
+
<i class="icon wxi-close" onclick={removeAll}></i>
|
|
29
30
|
</div>
|
|
30
31
|
<div class="list">
|
|
31
32
|
{#each data as obj (obj.id)}
|
|
32
33
|
<div class="row">
|
|
33
|
-
<div class="file-icon"
|
|
34
|
+
<div class="file-icon"></div>
|
|
34
35
|
<div class="name">{obj.name}</div>
|
|
35
36
|
{#if obj.file}
|
|
36
37
|
<div class="size">{formatSize(obj.file.size)}</div>
|
|
37
38
|
{/if}
|
|
38
39
|
<div class="controls">
|
|
39
|
-
{#if obj.status ===
|
|
40
|
-
<i class="icon wxi-spin wxi-loading"
|
|
41
|
-
{:else if obj.status ===
|
|
42
|
-
<i class="icon wxi-alert"
|
|
40
|
+
{#if obj.status === "client"}
|
|
41
|
+
<i class="icon wxi-spin wxi-loading"></i>
|
|
42
|
+
{:else if obj.status === "error"}
|
|
43
|
+
<i class="icon wxi-alert"></i>
|
|
44
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
45
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
43
46
|
<i
|
|
44
47
|
class="icon wxi-close"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
onclick={() => remove(obj.id)}
|
|
49
|
+
></i>
|
|
50
|
+
{:else if !obj.status || obj.status === "server"}
|
|
51
|
+
<i class="icon wxi-check"></i>
|
|
52
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
53
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
48
54
|
<i
|
|
49
55
|
class="icon wxi-close"
|
|
50
|
-
|
|
56
|
+
onclick={() => remove(obj.id)}
|
|
57
|
+
></i>
|
|
51
58
|
{/if}
|
|
52
59
|
</div>
|
|
53
60
|
</div>
|
|
@@ -90,9 +97,6 @@
|
|
|
90
97
|
text-overflow: ellipsis;
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
.controls {
|
|
94
|
-
}
|
|
95
|
-
|
|
96
100
|
.icon {
|
|
97
101
|
display: flex;
|
|
98
102
|
justify-content: center;
|
|
@@ -128,5 +132,4 @@
|
|
|
128
132
|
.wxi-alert {
|
|
129
133
|
display: flex;
|
|
130
134
|
}
|
|
131
|
-
|
|
132
135
|
</style>
|