@georapbox/files-dropzone-element 2.1.1 → 3.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/.editorconfig +15 -0
- package/.nvmrc +1 -0
- package/.prettierignore +6 -0
- package/.prettierrc +11 -0
- package/.vscode/extensions.json +8 -0
- package/.vscode/settings.json +8 -0
- package/.zed/settings.json +9 -0
- package/CHANGELOG.md +144 -0
- package/README.md +119 -103
- package/custom-elements-manifest.config.mjs +48 -0
- package/dist/custom-elements.json +509 -0
- package/dist/files-dropzone-defined.d.ts +1 -1
- package/dist/files-dropzone-defined.d.ts.map +1 -1
- package/dist/files-dropzone-defined.js +5 -5
- package/dist/files-dropzone-defined.js.map +4 -4
- package/dist/files-dropzone.d.ts +55 -68
- package/dist/files-dropzone.d.ts.map +1 -1
- package/dist/files-dropzone.js +5 -5
- package/dist/files-dropzone.js.map +4 -4
- package/dist/files-selector.d.ts +9 -0
- package/dist/files-selector.d.ts.map +1 -0
- package/dist/{utils/is-valid-file.d.ts → is-valid-file.d.ts} +1 -1
- package/dist/is-valid-file.d.ts.map +1 -0
- package/docs/css/main.css +190 -0
- package/docs/css/water.css +674 -0
- package/docs/favicon-32x32.png +0 -0
- package/docs/index.html +144 -0
- package/docs/js/main.js +154 -0
- package/docs/lib/files-dropzone.js +93 -0
- package/docs/lib/highlight/highlight-github.css +160 -0
- package/docs/lib/highlight/highlight.min.js +1160 -0
- package/eslint.config.mjs +42 -0
- package/package.json +52 -30
- package/scripts/build.mjs +32 -0
- package/scripts/copy-build-to-docs.mjs +17 -0
- package/scripts/dev.mjs +24 -0
- package/src/files-dropzone-defined.js +1 -1
- package/src/files-dropzone.js +70 -89
- package/test/files-dropzone-upgrade.test.js +39 -0
- package/test/files-dropzone.test.js +397 -0
- package/test/files-selector.test.js +96 -0
- package/test/is-valid-file.test.js +78 -0
- package/tsconfig.json +15 -0
- package/web-test-runner.config.js +13 -0
- package/dist/utils/files-selector.d.ts +0 -2
- package/dist/utils/files-selector.d.ts.map +0 -1
- package/dist/utils/is-valid-file.d.ts.map +0 -1
- /package/src/{utils/files-selector.js → files-selector.js} +0 -0
- /package/src/{utils/is-valid-file.js → is-valid-file.js} +0 -0
package/docs/index.html
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<meta name="color-scheme" content="light dark">
|
|
8
|
+
<title><files-dropzone></title>
|
|
9
|
+
<meta name="description" content="A custom element that creates a drag and drop zone for files">
|
|
10
|
+
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
|
|
11
|
+
<link rel="stylesheet" href="lib/highlight/highlight-github.css">
|
|
12
|
+
<link rel="stylesheet" href="css/water.css">
|
|
13
|
+
<link rel="stylesheet" href="css/main.css">
|
|
14
|
+
<script src="lib/highlight/highlight.min.js" defer></script>
|
|
15
|
+
<script type="module" src="js/main.js"></script>
|
|
16
|
+
</head>
|
|
17
|
+
<body class="no-js">
|
|
18
|
+
<script>document.body.classList.remove('no-js');</script>
|
|
19
|
+
|
|
20
|
+
<main class="container">
|
|
21
|
+
<noscript>
|
|
22
|
+
<div class="noscript-banner">This demo requires JavaScript to work.</div>
|
|
23
|
+
</noscript>
|
|
24
|
+
|
|
25
|
+
<h1><files-dropzone></h1>
|
|
26
|
+
|
|
27
|
+
<div class="component-description">
|
|
28
|
+
<p>A custom element that creates a drag and drop zone for files.</p>
|
|
29
|
+
<p><a href="https://github.com/georapbox/files-dropzone-element" target="_blank" rel="noreferrer noopener">Source code & documentation</a></p>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<h2 data-hide="no-js">Demo</h2>
|
|
33
|
+
|
|
34
|
+
<p data-hide="no-js">
|
|
35
|
+
<small><em>This is just a demo dropzone. Dropped files are not uploaded anywhere.</em></small>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<div class="dropzone-container" data-hide="no-js">
|
|
39
|
+
<files-dropzone></files-dropzone>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<details data-hide="no-js" open>
|
|
43
|
+
<summary>Dropped files</summary>
|
|
44
|
+
|
|
45
|
+
<p class="console-info">
|
|
46
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-info-lg" viewBox="0 0 16 16">
|
|
47
|
+
<path d="m9.708 6.075-3.024.379-.108.502.595.108c.387.093.464.232.38.619l-.975 4.577c-.255 1.183.14 1.74 1.067 1.74.72 0 1.554-.332 1.933-.789l.116-.549c-.263.232-.65.325-.905.325-.363 0-.494-.255-.402-.704l1.323-6.208Zm.091-2.755a1.32 1.32 0 1 1-2.64 0 1.32 1.32 0 0 1 2.64 0Z"/>
|
|
48
|
+
</svg>
|
|
49
|
+
<em>Open the browser's console to watch emitted events with more info of the dropped files.</em>
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<div class="dropped-files" id="droppedFiles"></div>
|
|
53
|
+
</details>
|
|
54
|
+
|
|
55
|
+
<details data-hide="no-js" open>
|
|
56
|
+
<summary>Customize component</summary>
|
|
57
|
+
|
|
58
|
+
<pre><code class="code-preview" id="codePreview"></code></pre>
|
|
59
|
+
|
|
60
|
+
<form autocomplete="off">
|
|
61
|
+
<fieldset>
|
|
62
|
+
<legend>Attributes</legend>
|
|
63
|
+
|
|
64
|
+
<div class="form-row">
|
|
65
|
+
<div class="form-col">
|
|
66
|
+
<label for="accept">accept</label>
|
|
67
|
+
<input type="text" id="accept" name="accept" list="acceptDatalist" placeholder="eg. image/*,.txt,application/pdf" data-attr>
|
|
68
|
+
|
|
69
|
+
<datalist id="acceptDatalist">
|
|
70
|
+
<option value="application/*"></option>
|
|
71
|
+
<option value="text/*"></option>
|
|
72
|
+
<option value="image/*"></option>
|
|
73
|
+
<option value="audio/*"></option>
|
|
74
|
+
<option value="video/*"></option>
|
|
75
|
+
<option value=".txt"></option>
|
|
76
|
+
<option value=".png"></option>
|
|
77
|
+
<option value=".jpg"></option>
|
|
78
|
+
<option value=".mp3"></option>
|
|
79
|
+
<option value=".mp4"></option>
|
|
80
|
+
<option value=".pdf"></option>
|
|
81
|
+
<option value=".html"></option>
|
|
82
|
+
<option value=".css"></option>
|
|
83
|
+
</datalist>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<div class="form-col">
|
|
87
|
+
<label for="max-files">max-files</label>
|
|
88
|
+
<input type="number" id="max-files" name="max-files" min="1" step="1" data-attr>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div class="form-row">
|
|
93
|
+
<div class="form-col">
|
|
94
|
+
<label for="max-size">max-size (bytes)</label>
|
|
95
|
+
<input type="number" id="max-size" name="max-size" min="0" step="1024" data-attr>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div class="form-col">
|
|
99
|
+
<label for="min-size">min-size (bytes)</label>
|
|
100
|
+
<input type="number" id="min-size" name="min-size" min="0" step="1024" data-attr>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div class="form-row" style="gap: 1rem;">
|
|
105
|
+
<div>
|
|
106
|
+
<input type="checkbox" id="disabled" name="disabled" data-attr>
|
|
107
|
+
<label for="disabled">disabled</label>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div>
|
|
111
|
+
<input type="checkbox" id="multiple" name="multiple" data-attr>
|
|
112
|
+
<label for="multiple">multiple</label>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<div>
|
|
116
|
+
<input type="checkbox" id="no-style" name="no-style" data-attr>
|
|
117
|
+
<label for="no-style">no-style</label>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</fieldset>
|
|
121
|
+
|
|
122
|
+
<fieldset>
|
|
123
|
+
<legend>Slots</legend>
|
|
124
|
+
|
|
125
|
+
<div class="form-row">
|
|
126
|
+
<div class="form-col">
|
|
127
|
+
<label for="slot">Default slot</label>
|
|
128
|
+
<input type="text" id="slot" name="slot" data-slot="default">
|
|
129
|
+
<p style="margin: 0;"><small><em>For the demo purposes, the slot is plain text. However, in reality you can use any valid HTML.</em></small></p>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</fieldset>
|
|
133
|
+
</form>
|
|
134
|
+
|
|
135
|
+
<button type="button" id="openFileDialogBtn" class="open-file-dialog-btn">
|
|
136
|
+
Open file dialog programmatically
|
|
137
|
+
</button>
|
|
138
|
+
</details>
|
|
139
|
+
|
|
140
|
+
<h2>License</h2>
|
|
141
|
+
<p>Licensed under the <a href="https://github.com/georapbox/files-dropzone-element/blob/main/LICENSE" target="_blank" rel="noreferrer noopener">The MIT License (MIT)</a></p>
|
|
142
|
+
</main>
|
|
143
|
+
</body>
|
|
144
|
+
</html>
|
package/docs/js/main.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
const url = window.location.href;
|
|
2
|
+
const isLocalhost = url.includes('127.0.0.1') || url.includes('localhost');
|
|
3
|
+
const componentUrl = isLocalhost ? '../../dist/files-dropzone.js' : '../lib/files-dropzone.js';
|
|
4
|
+
|
|
5
|
+
try {
|
|
6
|
+
const { FilesDropzone } = await import(componentUrl);
|
|
7
|
+
FilesDropzone.define();
|
|
8
|
+
} catch (err) {
|
|
9
|
+
console.error(err);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const droppedFilesList = document.getElementById('droppedFiles');
|
|
13
|
+
const codePreview = document.getElementById('codePreview');
|
|
14
|
+
const form = document.querySelector('form');
|
|
15
|
+
const dropzone = document.querySelector('files-dropzone');
|
|
16
|
+
const openFileDialogBtn = document.getElementById('openFileDialogBtn');
|
|
17
|
+
|
|
18
|
+
codePreview.textContent = '<files-dropzone></files-dropzone>';
|
|
19
|
+
|
|
20
|
+
window.hljs.highlightElement(codePreview);
|
|
21
|
+
|
|
22
|
+
function createCodePreview(dropzone) {
|
|
23
|
+
return dropzone.outerHTML.replace(/=""/g, '');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function createFilesList(files, status) {
|
|
27
|
+
if (!files.length) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const INITIAL_FILES_COUNT = 50;
|
|
32
|
+
|
|
33
|
+
const container = document.createElement('div');
|
|
34
|
+
|
|
35
|
+
const title = Object.assign(document.createElement('h3'), {
|
|
36
|
+
className: 'dropped-files__title',
|
|
37
|
+
textContent: `${status === 'accepted' ? 'Accepted' : 'Rejected'} files (${files.length})`
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const list = Object.assign(document.createElement('ul'), {
|
|
41
|
+
className: 'dropped-files__list'
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
files.forEach((item, index) => {
|
|
45
|
+
const file = status === 'accepted' ? item : item.file;
|
|
46
|
+
|
|
47
|
+
const listItem = Object.assign(document.createElement('li'), {
|
|
48
|
+
className: `dropped-files__list-item dropped-files__list-item--${status}`,
|
|
49
|
+
hidden: index >= INITIAL_FILES_COUNT
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const fileInfo = document.createElement('div');
|
|
53
|
+
fileInfo.append(document.createTextNode(file.name));
|
|
54
|
+
|
|
55
|
+
const fileSize = document.createElement('span');
|
|
56
|
+
fileSize.className = 'dropped-files__file-size';
|
|
57
|
+
fileSize.textContent = ` - ${file.size} bytes`;
|
|
58
|
+
|
|
59
|
+
fileInfo.appendChild(fileSize);
|
|
60
|
+
listItem.appendChild(fileInfo);
|
|
61
|
+
|
|
62
|
+
if (status === 'rejected') {
|
|
63
|
+
const errorsList = document.createElement('ul');
|
|
64
|
+
errorsList.className = 'dropped-files__errors';
|
|
65
|
+
|
|
66
|
+
item.errors.forEach(({ message }) => {
|
|
67
|
+
const errorItem = document.createElement('li');
|
|
68
|
+
errorItem.textContent = message;
|
|
69
|
+
errorsList.appendChild(errorItem);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
listItem.appendChild(errorsList);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
list.appendChild(listItem);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const showAllBtn = Object.assign(document.createElement('button'), {
|
|
79
|
+
type: 'button',
|
|
80
|
+
className: 'dropped-files__show-all',
|
|
81
|
+
textContent: 'Show all'
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
container.appendChild(title);
|
|
85
|
+
container.appendChild(list);
|
|
86
|
+
|
|
87
|
+
if (files.length > INITIAL_FILES_COUNT) {
|
|
88
|
+
container.appendChild(showAllBtn);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return container;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
droppedFilesList.addEventListener('click', evt => {
|
|
95
|
+
const target = evt.target;
|
|
96
|
+
|
|
97
|
+
if (target.matches('.dropped-files__show-all')) {
|
|
98
|
+
target.previousElementSibling.querySelectorAll('li').forEach(item => (item.hidden = false));
|
|
99
|
+
target.remove();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
form.addEventListener('input', evt => {
|
|
104
|
+
const target = evt.target;
|
|
105
|
+
const { name, value } = target;
|
|
106
|
+
|
|
107
|
+
if (target.hasAttribute('data-slot')) {
|
|
108
|
+
dropzone.textContent = value;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (target.hasAttribute('data-attr')) {
|
|
112
|
+
switch (target.type) {
|
|
113
|
+
case 'checkbox':
|
|
114
|
+
target.checked ? dropzone.setAttribute(name, '') : dropzone.removeAttribute(name);
|
|
115
|
+
break;
|
|
116
|
+
default:
|
|
117
|
+
value ? dropzone.setAttribute(name, value) : dropzone.removeAttribute(name);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
codePreview.textContent = createCodePreview(dropzone);
|
|
122
|
+
|
|
123
|
+
window.hljs.highlightElement(codePreview);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
document.addEventListener('dropzone-drop', evt => {
|
|
127
|
+
console.log('dropzone-drop ->', evt.detail);
|
|
128
|
+
|
|
129
|
+
const { acceptedFiles, rejectedFiles } = evt.detail;
|
|
130
|
+
const acceptedFilesList = createFilesList(acceptedFiles, 'accepted');
|
|
131
|
+
const rejectedFilesList = createFilesList(rejectedFiles, 'rejected');
|
|
132
|
+
|
|
133
|
+
droppedFilesList.replaceChildren();
|
|
134
|
+
|
|
135
|
+
if (acceptedFilesList) {
|
|
136
|
+
droppedFilesList.appendChild(acceptedFilesList);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (rejectedFilesList) {
|
|
140
|
+
droppedFilesList.appendChild(rejectedFilesList);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
document.addEventListener('dropzone-error', evt => {
|
|
145
|
+
console.log('dropzone-error ->', evt.detail.error);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
openFileDialogBtn.addEventListener('click', () => {
|
|
149
|
+
dropzone.openFileDialog();
|
|
150
|
+
|
|
151
|
+
if (dropzone.hasAttribute('disabled')) {
|
|
152
|
+
alert('Dropzone is disabled. File dialog will not open programmatically.');
|
|
153
|
+
}
|
|
154
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @georapbox/files-dropzone-element
|
|
3
|
+
* A custom element that creates a drag and drop zone for files
|
|
4
|
+
*
|
|
5
|
+
* @version 3.0.0
|
|
6
|
+
* @homepage https://github.com/georapbox/files-dropzone-element#readme
|
|
7
|
+
* @author George Raptis <georapbox@gmail.com>
|
|
8
|
+
* @license MIT
|
|
9
|
+
*/
|
|
10
|
+
function c(o,e=""){if(!e)return!0;let t=[...new Set(e.split(",").map(r=>r.trim()).filter(Boolean))],i=o.type,s=i.replace(/\/.*$/,"");for(let r of t)if(r.charAt(0)==="."){if(o.name.toLowerCase().indexOf(r.toLowerCase(),o.name.length-r.length)!==-1)return!0}else if(/\/\*$/.test(r)){if(s===r.replace(/\/.*$/,""))return!0}else if(i===r)return!0;return!1}var v=new Map([["aac","audio/aac"],["abw","application/x-abiword"],["arc","application/x-freearc"],["avif","image/avif"],["avi","video/x-msvideo"],["azw","application/vnd.amazon.ebook"],["bin","application/octet-stream"],["bmp","image/bmp"],["bz","application/x-bzip"],["bz2","application/x-bzip2"],["cda","application/x-cdf"],["csh","application/x-csh"],["css","text/css"],["csv","text/csv"],["doc","application/msword"],["docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"],["eot","application/vnd.ms-fontobject"],["epub","application/epub+zip"],["gz","application/gzip"],["gif","image/gif"],["heic","image/heic"],["heif","image/heif"],["htm","text/html"],["html","text/html"],["ico","image/vnd.microsoft.icon"],["ics","text/calendar"],["jar","application/java-archive"],["jpeg","image/jpeg"],["jpg","image/jpeg"],["jxl","image/jxl"],["js","text/javascript"],["json","application/json"],["jsonld","application/ld+json"],["markdown","text/markdown"],["md","text/markdown"],["mid","audio/midi"],["midi","audio/midi"],["mjs","text/javascript"],["mp3","audio/mpeg"],["mp4","video/mp4"],["mpeg","video/mpeg"],["mpkg","application/vnd.apple.installer+xml"],["odp","application/vnd.oasis.opendocument.presentation"],["ods","application/vnd.oasis.opendocument.spreadsheet"],["odt","application/vnd.oasis.opendocument.text"],["oga","audio/ogg"],["ogv","video/ogg"],["ogx","application/ogg"],["opus","audio/opus"],["otf","font/otf"],["png","image/png"],["pdf","application/pdf"],["php","application/x-httpd-php"],["ppt","application/vnd.ms-powerpoint"],["pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"],["rar","application/vnd.rar"],["rtf","application/rtf"],["sh","application/x-sh"],["svg","image/svg+xml"],["swf","application/x-shockwave-flash"],["tar","application/x-tar"],["tif","image/tiff"],["tiff","image/tiff"],["ts","video/mp2t"],["ttf","font/ttf"],["txt","text/plain"],["vsd","application/vnd.visio"],["wav","audio/wav"],["weba","audio/webm"],["webm","video/webm"],["webp","image/webp"],["woff","font/woff"],["woff2","font/woff2"],["xhtml","application/xhtml+xml"],["xls","application/vnd.ms-excel"],["xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],["xml","application/xml"],["xul","application/vnd.mozilla.xul+xml"],["zip","application/zip"],["7z","application/x-7z-compressed"],["mkv","video/x-matroska"],["mov","video/quicktime"],["msg","application/vnd.ms-outlook"]]),f=[".DS_Store","Thumbs.db"],E=o=>{let{name:e}=o;if(e&&e.lastIndexOf(".")!==-1&&!o.type){let i=(e.split(".").pop()||"").toLowerCase(),s=v.get(i);s&&Object.defineProperty(o,"type",{value:s,writable:!1,configurable:!1,enumerable:!0})}return o},m=(o,e)=>{let t=E(o);if(typeof t.path!="string"){let{webkitRelativePath:i}=o;Object.defineProperty(t,"path",{value:typeof e=="string"?e:i||o.name,writable:!1,configurable:!1,enumerable:!0})}return t},h=async o=>await new Promise((e,t)=>{o.readEntries(e,t)}),z=async o=>{let e=[],t=await h(o);for(;t.length>0;)e.push(...t),t=await h(o);return e},x=o=>new Promise((e,t)=>{o.file(i=>e(m(i,o.fullPath)),t)}),y=async o=>{let e=[],t=[];for(let i of o){if(i.kind!=="file")continue;let s=i.getAsEntry?i.getAsEntry():i.webkitGetAsEntry();t.push(s)}for(;t.length>0;){let i=t.shift();if(i)if(i.isFile){let s=await x(i);f.indexOf(s.name)===-1&&e.push(s)}else i.isDirectory&&t.push(...await z(i.createReader()));else continue}return e},u=async o=>{let e=[];for(let t of o)f.indexOf(t.name)===-1&&e.push(m(t));return e},a=async o=>o.dataTransfer?o.dataTransfer.items?await y(o.dataTransfer.items):await u(o.dataTransfer.files):await u(o.target.files);var w=String.raw,O=String.raw,b=document.createElement("template"),L=w`
|
|
11
|
+
*,
|
|
12
|
+
*::before,
|
|
13
|
+
*::after {
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
:host([hidden]),
|
|
18
|
+
[hidden] {
|
|
19
|
+
display: none !important;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
:host {
|
|
23
|
+
--dropzone-border-width: 2px;
|
|
24
|
+
--dropzone-border-style: dashed;
|
|
25
|
+
--dropzone-border-radius: 0.25rem;
|
|
26
|
+
--dropzone-border-color: #6c757d;
|
|
27
|
+
--dropzone-border-color-dragover: #0d6efd;
|
|
28
|
+
--dropzone-border-color-hover: var(--dropzone-border-color-dragover);
|
|
29
|
+
--dropzone-background-color: #ffffff;
|
|
30
|
+
--dropzone-background-color-dragover: #f4f4f5;
|
|
31
|
+
--dropzone-background-color-hover: var(--dropzone-background-color-dragover);
|
|
32
|
+
--dropzone-body-color: #3f3f46;
|
|
33
|
+
--dropzone-body-color-dragover: var(--dropzone-body-color);
|
|
34
|
+
--dropzone-body-color-hover: var(--dropzone-body-color-dragover);
|
|
35
|
+
--dropzone-focus-shadow-rgb: 49, 132, 253;
|
|
36
|
+
--dropzone-focus-box-shadow: 0 0 0 0.25rem rgba(var(--dropzone-focus-shadow-rgb), 0.5);
|
|
37
|
+
--transition-duration: 0.2s; /* for backwards compatibility */
|
|
38
|
+
--dropzone-transition-duration: var(--transition-duration);
|
|
39
|
+
|
|
40
|
+
display: block;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:host(:not([no-style])) .dropzone {
|
|
44
|
+
border: var(--dropzone-border-width) var(--dropzone-border-style) var(--dropzone-border-color);
|
|
45
|
+
border-radius: var(--dropzone-border-radius);
|
|
46
|
+
padding: 3rem 1rem;
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
background-color: var(--dropzone-background-color);
|
|
49
|
+
color: var(--dropzone-body-color);
|
|
50
|
+
text-align: center;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
transition:
|
|
53
|
+
border var(--dropzone-transition-duration) ease-in-out,
|
|
54
|
+
background-color var(--dropzone-transition-duration) ease-in-out,
|
|
55
|
+
color var(--dropzone-transition-duration) ease-in-out,
|
|
56
|
+
box-shadow var(--dropzone-transition-duration) ease-in-out;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:host(:not([no-style])[disabled]) .dropzone {
|
|
60
|
+
opacity: 0.8;
|
|
61
|
+
cursor: not-allowed;
|
|
62
|
+
user-select: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:host(:not([no-style]):not([disabled])) .dropzone--dragover {
|
|
66
|
+
border-color: var(--dropzone-border-color-dragover);
|
|
67
|
+
background-color: var(--dropzone-background-color-dragover);
|
|
68
|
+
color: var(--dropzone-body-color-dragover);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:host(:not([no-style]):not([disabled])) .dropzone:focus-visible {
|
|
72
|
+
outline: none;
|
|
73
|
+
box-shadow: var(--dropzone-focus-box-shadow);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@media (hover: hover) {
|
|
77
|
+
:host(:not([no-style]):not([disabled])) .dropzone:not(.dropzone--dragover):hover {
|
|
78
|
+
border-color: var(--dropzone-border-color-hover);
|
|
79
|
+
background-color: var(--dropzone-background-color-hover);
|
|
80
|
+
color: var(--dropzone-body-color-hover);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
`;b.innerHTML=O`
|
|
84
|
+
<style>
|
|
85
|
+
${L}
|
|
86
|
+
</style>
|
|
87
|
+
|
|
88
|
+
<input type="file" id="file-input" hidden />
|
|
89
|
+
|
|
90
|
+
<div part="dropzone" class="dropzone" id="dropzone" tabindex="0" role="button" aria-disabled="false">
|
|
91
|
+
<slot><span>Drag 'n' drop files here, or click to select files</span></slot>
|
|
92
|
+
</div>
|
|
93
|
+
`;var g=class o extends HTMLElement{static ERROR_CODES={FILE_DIALOG_OPEN_FAILED:"FILE_DIALOG_OPEN_FAILED",FILE_INPUT_CHANGE_FAILED:"FILE_INPUT_CHANGE_FAILED",DROP_EVENT_PROCESSING_FAILED:"DROP_EVENT_PROCESSING_FAILED",UNKNOWN_ERROR:"UNKNOWN_ERROR"};static REJECTION_CODES={TOO_MANY_FILES:"TOO_MANY_FILES",FILE_TOO_LARGE:"FILE_TOO_LARGE",FILE_TOO_SMALL:"FILE_TOO_SMALL",INVALID_MIME_TYPE:"INVALID_MIME_TYPE"};#t=null;#e=null;constructor(){super(),this.shadowRoot||this.attachShadow({mode:"open",delegatesFocus:!0}).appendChild(b.content.cloneNode(!0)),this.shadowRoot&&(this.#t=this.shadowRoot.getElementById("file-input"),this.#e=this.shadowRoot.getElementById("dropzone"))}static get observedAttributes(){return["accept","disabled","multiple"]}attributeChangedCallback(e,t,i){e==="accept"&&t!==i&&this.#t&&(this.#t.accept=this.accept),e==="disabled"&&t!==i&&this.#t&&(this.#t.disabled=this.disabled,this.disabled?(this.#e?.removeAttribute("tabindex"),this.#e?.setAttribute("aria-disabled","true")):(this.#e?.setAttribute("tabindex","0"),this.#e?.setAttribute("aria-disabled","false"))),e==="multiple"&&t!==i&&this.#t&&(this.#t.multiple=this.multiple)}connectedCallback(){this.#i("accept"),this.#i("disabled"),this.#i("maxFiles"),this.#i("maxSize"),this.#i("minSize"),this.#i("multiple"),this.#i("autoFocus"),this.#i("noStyle"),this.#t?.addEventListener("change",this.#r),this.#e?.addEventListener("dragenter",this.#s),this.#e?.addEventListener("dragover",this.#n),this.#e?.addEventListener("dragleave",this.#a),this.#e?.addEventListener("drop",this.#d),this.#e?.addEventListener("click",this.#l),this.#e?.addEventListener("keyup",this.#p),this.autoFocus&&this.#e?.focus()}disconnectedCallback(){this.#t?.removeEventListener("change",this.#r),this.#e?.removeEventListener("dragenter",this.#s),this.#e?.removeEventListener("dragover",this.#n),this.#e?.removeEventListener("dragleave",this.#a),this.#e?.removeEventListener("drop",this.#d),this.#e?.removeEventListener("click",this.#l),this.#e?.removeEventListener("keyup",this.#p)}get accept(){return this.getAttribute("accept")||""}set accept(e){this.setAttribute("accept",e!=null?e.toString():e)}get disabled(){return this.hasAttribute("disabled")}set disabled(e){this.toggleAttribute("disabled",!!e)}get maxFiles(){let e=Number(this.getAttribute("max-files"))||0;return e<=0?1/0:Math.floor(Math.abs(e))}set maxFiles(e){this.setAttribute("max-files",e!=null?e.toString():e)}get maxSize(){let e=this.getAttribute("max-size");if(e===null)return 1/0;let t=Number(e);return Number.isNaN(t)?1/0:t}set maxSize(e){this.setAttribute("max-size",e!=null?e.toString():e)}get minSize(){let e=this.getAttribute("min-size");if(e===null)return 0;let t=Number(e);return Number.isNaN(t)?0:t}set minSize(e){this.setAttribute("min-size",e!=null?e.toString():e)}get multiple(){return this.hasAttribute("multiple")}set multiple(e){this.toggleAttribute("multiple",!!e)}get autoFocus(){return this.hasAttribute("auto-focus")}set autoFocus(e){this.toggleAttribute("auto-focus",!!e)}get noStyle(){return this.hasAttribute("no-style")}set noStyle(e){this.toggleAttribute("no-style",!!e)}#o(e,t,{cancelable:i=!1}={}){let s={bubbles:!0,composed:!0,cancelable:i},r=t===void 0?new Event(e,s):new CustomEvent(e,{...s,detail:t});return this.dispatchEvent(r)}#r=async e=>{try{this.#c(await a(e))}catch(t){this.#o("dropzone-error",{code:o.ERROR_CODES.FILE_INPUT_CHANGE_FAILED,error:t})}};#s=()=>{this.disabled||this.#o("dropzone-dragenter")};#n=e=>{if(e.preventDefault(),this.disabled){e.dataTransfer.dropEffect="none";return}e.dataTransfer.dropEffect="copy",this.#e&&(this.#e.classList.add("dropzone--dragover"),this.#e.part.add("dropzone--dragover")),this.#o("dropzone-dragover")};#a=()=>{this.disabled||(this.#e&&(this.#e.classList.remove("dropzone--dragover"),this.#e.part.remove("dropzone--dragover")),this.#o("dropzone-dragleave"))};#d=async e=>{if(!this.disabled){e.preventDefault(),this.#e&&(this.#e.classList.remove("dropzone--dragover"),this.#e.part.remove("dropzone--dragover"));try{this.#c(await a(e))}catch(t){this.#o("dropzone-error",{code:o.ERROR_CODES.DROP_EVENT_PROCESSING_FAILED,error:t})}}};#l=()=>{this.disabled||this.openFileDialog()};#p=e=>{this.disabled||(e.key===" "||e.key==="Enter")&&this.openFileDialog()};#c(e){if(!Array.isArray(e)||!e.length)return;let t=[],i=[],s=e.length;if(!this.multiple&&s>1)for(let r of e)i.push({file:r,errors:[{code:o.REJECTION_CODES.TOO_MANY_FILES,message:"Too many files selected. Only 1 file is allowed."}]});else if(this.multiple&&s>this.maxFiles)for(let r of e)i.push({file:r,errors:[{code:o.REJECTION_CODES.TOO_MANY_FILES,message:`Too many files selected. Only ${this.maxFiles} ${this.maxFiles>1?"files are":"file is"} allowed.`}]});else for(let r of e){let d=c(r,this.accept),l=r.size>this.maxSize,p=r.size<this.minSize;if(d&&!l&&!p)t.push(r);else{let n=[];d||n.push({code:o.REJECTION_CODES.INVALID_MIME_TYPE,message:`File type "${r.type}" is not accepted.`}),l&&n.push({code:o.REJECTION_CODES.FILE_TOO_LARGE,message:`File size ${r.size} exceeds the maximum size of ${this.maxSize}.`}),p&&n.push({code:o.REJECTION_CODES.FILE_TOO_SMALL,message:`File size ${r.size} is smaller than the minimum size of ${this.minSize}.`}),i.push({file:r,errors:n})}}this.#o("dropzone-drop",{acceptedFiles:t,rejectedFiles:i}),t.length>0&&this.#o("dropzone-drop-accepted",{acceptedFiles:t}),i.length>0&&this.#o("dropzone-drop-rejected",{rejectedFiles:i}),this.#t&&(this.#t.value=this.#t.defaultValue)}openFileDialog(){if(!(this.disabled||!this.#t)){if("showPicker"in HTMLInputElement.prototype&&typeof this.#t.showPicker=="function"){try{this.#t.showPicker()}catch(e){this.#o("dropzone-error",{code:o.ERROR_CODES.FILE_DIALOG_OPEN_FAILED,error:e})}return}this.#t.click()}}#i(e){let t=this;if(Object.hasOwn(t,e)){let i=t[e];delete t[e],t[e]=i}}static define(e="files-dropzone"){typeof window>"u"||window.customElements.get(e)||window.customElements.define(e,o)}};export{g as FilesDropzone};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
pre code.hljs {
|
|
2
|
+
display: block;
|
|
3
|
+
overflow-x: auto;
|
|
4
|
+
padding: 1em;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
code.hljs {
|
|
8
|
+
padding: 3px 5px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
:root {
|
|
12
|
+
--italic: italic;
|
|
13
|
+
--bold: 700;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/*!
|
|
17
|
+
* Theme: GitHub
|
|
18
|
+
* Description: Light theme as seen on github.com
|
|
19
|
+
* Author: github.com
|
|
20
|
+
* Maintainer: @Hirse
|
|
21
|
+
* Updated: 2021-05-15
|
|
22
|
+
*
|
|
23
|
+
* Outdated base version: https://github.com/primer/github-syntax-light
|
|
24
|
+
* Current colors taken from GitHub's CSS
|
|
25
|
+
*/
|
|
26
|
+
:root {
|
|
27
|
+
--text-color: #24292e;
|
|
28
|
+
--background-color: #ffffff;
|
|
29
|
+
--keyword-color: #d73a49;
|
|
30
|
+
--title-color: #6f42c1;
|
|
31
|
+
--syntax-color: #005cc5;
|
|
32
|
+
--string-color: #032f62;
|
|
33
|
+
--built-in-color: #e36209;
|
|
34
|
+
--code-color: #6a737d;
|
|
35
|
+
--name-color: #22863a;
|
|
36
|
+
--subst-color: #24292e;
|
|
37
|
+
--section-color: #005cc5;
|
|
38
|
+
--bullet-color: #735c0f;
|
|
39
|
+
--emphasis-color: #24292e;
|
|
40
|
+
--strong-color: #24292e;
|
|
41
|
+
--addition-color: #22863a;
|
|
42
|
+
--deletion-color: #b31d28;
|
|
43
|
+
--addition-background: #f0fff4;
|
|
44
|
+
--deletion-background: #ffeef0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@media (prefers-color-scheme: dark) {
|
|
48
|
+
:root {
|
|
49
|
+
--text-color: #c9d1d9;
|
|
50
|
+
--background-color: #0d1117;
|
|
51
|
+
--keyword-color: #ff7b72;
|
|
52
|
+
--title-color: #d2a8ff;
|
|
53
|
+
--syntax-color: #79c0ff;
|
|
54
|
+
--string-color: #a5d6ff;
|
|
55
|
+
--built-in-color: #ffa657;
|
|
56
|
+
--code-color: #8b949e;
|
|
57
|
+
--name-color: #7ee787;
|
|
58
|
+
--subst-color: #c9d1d9;
|
|
59
|
+
--section-color: #1f6feb;
|
|
60
|
+
--bullet-color: #f2cc60;
|
|
61
|
+
--emphasis-color: #c9d1d9;
|
|
62
|
+
--strong-color: #c9d1d9;
|
|
63
|
+
--addition-color: #aff5b4;
|
|
64
|
+
--deletion-color: #ffdcd7;
|
|
65
|
+
--addition-background: #033a16;
|
|
66
|
+
--deletion-background: #67060c;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.hljs {
|
|
71
|
+
color: var(--text-color);
|
|
72
|
+
background: var(--background-color);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.hljs-doctag,
|
|
76
|
+
.hljs-keyword,
|
|
77
|
+
.hljs-meta .hljs-keyword,
|
|
78
|
+
.hljs-template-tag,
|
|
79
|
+
.hljs-template-variable,
|
|
80
|
+
.hljs-type,
|
|
81
|
+
.hljs-variable.language_ {
|
|
82
|
+
color: var(--keyword-color);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.hljs-title,
|
|
86
|
+
.hljs-title.class_,
|
|
87
|
+
.hljs-title.class_.inherited__,
|
|
88
|
+
.hljs-title.function_ {
|
|
89
|
+
color: var(--title-color);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.hljs-attr,
|
|
93
|
+
.hljs-attribute,
|
|
94
|
+
.hljs-literal,
|
|
95
|
+
.hljs-meta,
|
|
96
|
+
.hljs-number,
|
|
97
|
+
.hljs-operator,
|
|
98
|
+
.hljs-selector-attr,
|
|
99
|
+
.hljs-selector-class,
|
|
100
|
+
.hljs-selector-id,
|
|
101
|
+
.hljs-variable {
|
|
102
|
+
color: var(--syntax-color);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.hljs-meta .hljs-string,
|
|
106
|
+
.hljs-regexp,
|
|
107
|
+
.hljs-string {
|
|
108
|
+
color: var(--string-color);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.hljs-built_in,
|
|
112
|
+
.hljs-symbol {
|
|
113
|
+
color: var(--built-in-color);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.hljs-code,
|
|
117
|
+
.hljs-comment,
|
|
118
|
+
.hljs-formula {
|
|
119
|
+
color: var(--code-color);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.hljs-name,
|
|
123
|
+
.hljs-quote,
|
|
124
|
+
.hljs-selector-pseudo,
|
|
125
|
+
.hljs-selector-tag {
|
|
126
|
+
color: var(--name-color);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.hljs-subst {
|
|
130
|
+
color: var(--subst-color);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.hljs-section {
|
|
134
|
+
color: var(--section-color);
|
|
135
|
+
font-weight: var(--bold);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.hljs-bullet {
|
|
139
|
+
color: var(--bullet-color);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.hljs-emphasis {
|
|
143
|
+
color: var(--emphasis-color);
|
|
144
|
+
font-style: var(--italic);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.hljs-strong {
|
|
148
|
+
color: var(--strong-color);
|
|
149
|
+
font-weight: var(--bold);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.hljs-addition {
|
|
153
|
+
color: var(--addition-color);
|
|
154
|
+
background-color: var(--addition-background);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.hljs-deletion {
|
|
158
|
+
color: var(--deletion-color);
|
|
159
|
+
background-color: var(--deletion-background);
|
|
160
|
+
}
|